diff options
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/dri/i830')
23 files changed, 9463 insertions, 0 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/Makefile b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/Makefile new file mode 100644 index 000000000..3276d396e --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/Makefile @@ -0,0 +1,31 @@ + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = i830_dri.so + +DRIVER_SOURCES = \ + i830_context.c \ + i830_debug.c \ + i830_ioctl.c \ + i830_render.c \ + i830_screen.c \ + i830_span.c \ + i830_state.c \ + i830_tex.c \ + i830_texmem.c \ + i830_texstate.c \ + i830_tris.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(MINIGLX_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + + + +include ../Makefile.template + +symlinks: diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_3d_reg.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_3d_reg.h new file mode 100644 index 000000000..fa6f407ef --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_3d_reg.h @@ -0,0 +1,677 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_3d_reg.h,v 1.4 2002/12/10 01:26:53 dawes Exp $ */ +#define I830_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) + +#define CMD_3D (0x3<<29) + +/* 3DPRIMITIVE, p104 */ +#define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) +#define PRIM3D_INDIRECT_SEQ ((1<<23) | PRIM3D_INLINE) +#define PRIM3D_INDICES ((1<<23) | PRIM3D_INLINE | (1<<17)) + +#define PRIM3D_INLINE_CNT(used) ((used / 4) - 2) +#define PRIM3D_INDICES_CNT(num_indices) ((num_indices + 1) / 2) +#define PRIM3D_INDIRECT_CNT(verts) (verts) + +#define PRIM3D_TRILIST 0 +#define PRIM3D_TRISTRIP (0x1<<18) +#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) +#define PRIM3D_TRIFAN (0x3<<18) +#define PRIM3D_POLY (0x4<<18) +#define PRIM3D_LINELIST (0x5<<18) +#define PRIM3D_LINESTRIP (0x6<<18) +#define PRIM3D_RECTLIST (0x7<<18) +#define PRIM3D_POINTLIST (0x8<<18) +#define PRIM3D_DIB (0x9<<18) + +/* STATE3D_ANTI_ALIASING, p 123 */ +#define STATE3D_AA_CMD (CMD_3D | (0x06<<24)) + +#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) +#define AA_LINE_ECAAR_WIDTH_0_5 0 +#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) +#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) +#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) + +#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) +#define AA_LINE_REGION_WIDTH_0_5 0 +#define AA_LINE_REGION_WIDTH_1_0 (1<<6) +#define AA_LINE_REGION_WIDTH_2_0 (2<<6) +#define AA_LINE_REGION_WIDTH_4_0 (3<<6) + +#define AA_LINE_ENABLE ((1<<1) | 1) +#define AA_LINE_DISABLE (1<<1) + +/* STATE3D_BUFFER_INFO, p 124 */ +#define STATE3D_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) +/* Dword 1 */ +#define BUF_3D_ID_COLOR_BACK (0x3<<24) +#define BUF_3D_ID_DEPTH (0x7<<24) +#define BUF_3D_USE_FENCE (1<<23) +#define BUF_3D_TILED_SURFACE (1<<22) +#define BUF_3D_TILE_WALK_X 0 +#define BUF_3D_TILE_WALK_Y (1<<21) +#define BUF_3D_PITCH(x) ((x)<<2) +/* Dword 2 */ +#define BUF_3D_ADDR(x) ((x) & ~0x3) + +/* STATE3D_COLOR_FACTOR_0, p127 */ +#define STATE3D_COLOR_FACTOR_CMD(stage) (CMD_3D | (0x1d<<24) | ((0x90 + (stage))<<16)) + +/* STATE3D_CONSTANT_BLEND_COLOR, p128 */ +#define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) + +/* STATE3D_DEFAULT_DIFFUSE, p128 */ +#define STATE3D_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) + +/* STATE3D_DEFAULT_SPECULAR, p129 */ +#define STATE3D_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) + +/* STATE3D_DEFAULT_Z, p129 */ +#define STATE3D_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) + +/* STATE3D_DEST_BUFFER_VARIABLES, p130 */ +#define STATE3D_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) +/* Dword 1 */ +#define DSTORG_HORT_BIAS(x) ((x)<<20) +#define DSTORG_VERT_BIAS(x) ((x)<<16) +#define COLOR_4_2_2_CHNL_WRT_ALL 0 +#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) +#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) +#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) +#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) +#define COLR_BUF_8BIT 0 +#define COLR_BUF_RGB555 (1<<8) +#define COLR_BUF_RGB565 (2<<8) +#define COLR_BUF_ARGB8888 (3<<8) +#define DEPTH_IS_Z 0 +#define DEPTH_IS_W (1<<6) +#define DEPTH_FRMT_16_FIXED 0 +#define DEPTH_FRMT_16_FLOAT (1<<2) +#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) +#define DEPTH_FRMT_24_FLOAT_8_OTHER (3<<2) +#define VERT_LINE_STRIDE_1 (1<<1) +#define VERT_LINE_STRIDE_0 0 +#define VERT_LINE_STRIDE_OFS_1 1 +#define VERT_LINE_STRIDE_OFS_0 0 + +/* STATE3D_DRAWING_RECTANGLE, p133 */ +#define STATE3D_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) +/* Dword 1 */ +#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) +#define DRAW_DITHER_OFS_X(x) ((x)<<26) +#define DRAW_DITHER_OFS_Y(x) ((x)<<24) +/* Dword 2 */ +#define DRAW_YMIN(x) ((x)<<16) +#define DRAW_XMIN(x) (x) +/* Dword 3 */ +#define DRAW_YMAX(x) ((x)<<16) +#define DRAW_XMAX(x) (x) +/* Dword 4 */ +#define DRAW_YORG(x) ((x)<<16) +#define DRAW_XORG(x) (x) + +/* STATE3D_ENABLES_1, p136 */ +#define STATE3D_ENABLES_1_CMD (CMD_3D|(0x3<<24)) +#define ENABLE_LOGIC_OP_MASK ((1<<23)|(1<<22)) +#define ENABLE_LOGIC_OP ((1<<23)|(1<<22)) +#define DISABLE_LOGIC_OP (1<<23) +#define ENABLE_STENCIL_TEST ((1<<21)|(1<<20)) +#define DISABLE_STENCIL_TEST (1<<21) +#define ENABLE_DEPTH_BIAS ((1<<11)|(1<<10)) +#define DISABLE_DEPTH_BIAS (1<<11) +#define ENABLE_SPEC_ADD_MASK ((1<<9)|(1<<8)) +#define ENABLE_SPEC_ADD ((1<<9)|(1<<8)) +#define DISABLE_SPEC_ADD (1<<9) +#define ENABLE_DIS_FOG_MASK ((1<<7)|(1<<6)) + /* prefixed I830 because ENABLE_FOG defined elsewhere */ +#define I830_ENABLE_FOG ((1<<7)|(1<<6)) +#define I830_DISABLE_FOG (1<<7) +#define ENABLE_DIS_ALPHA_TEST_MASK ((1<<5)|(1<<4)) +#define ENABLE_ALPHA_TEST ((1<<5)|(1<<4)) +#define DISABLE_ALPHA_TEST (1<<5) +#define ENABLE_DIS_CBLEND_MASK ((1<<3)|(1<<2)) +#define ENABLE_COLOR_BLEND ((1<<3)|(1<<2)) +#define DISABLE_COLOR_BLEND (1<<3) +#define ENABLE_DIS_DEPTH_TEST_MASK ((1<<1)|1) +#define ENABLE_DEPTH_TEST ((1<<1)|1) +#define DISABLE_DEPTH_TEST (1<<1) + +/* STATE3D_ENABLES_2, p138 */ +#define STATE3D_ENABLES_2_CMD (CMD_3D|(0x4<<24)) +#define ENABLE_STENCIL_WRITE ((1<<21)|(1<<20)) +#define DISABLE_STENCIL_WRITE (1<<21) +#define ENABLE_TEX_CACHE ((1<<17)|(1<<16)) +#define DISABLE_TEX_CACHE (1<<17) +#define ENABLE_DITHER ((1<<9)|(1<<8)) +#define DISABLE_DITHER (1<<9) +#define ENABLE_COLOR_MASK (1<<10) +#define WRITEMASK_ALPHA (1<<7) +#define WRITEMASK_ALPHA_SHIFT 7 +#define WRITEMASK_RED (1<<6) +#define WRITEMASK_RED_SHIFT 6 +#define WRITEMASK_GREEN (1<<5) +#define WRITEMASK_GREEN_SHIFT 5 +#define WRITEMASK_BLUE (1<<4) +#define WRITEMASK_BLUE_SHIFT 4 +#define WRITEMASK_MASK ((1<<4)|(1<<5)|(1<<6)|(1<<7)) +#define ENABLE_COLOR_WRITE ((1<<3)|(1<<2)) +#define DISABLE_COLOR_WRITE (1<<3) +#define ENABLE_DIS_DEPTH_WRITE_MASK 0x3 +#define ENABLE_DEPTH_WRITE ((1<<1)|1) +#define DISABLE_DEPTH_WRITE (1<<1) + +/* STATE3D_FOG_COLOR, p139 */ +#define STATE3D_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) +#define FOG_COLOR_RED(x) ((x)<<16) +#define FOG_COLOR_GREEN(x) ((x)<<8) +#define FOG_COLOR_BLUE(x) (x) + +/* STATE3D_FOG_MODE, p140 */ +#define STATE3D_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) +/* Dword 1 */ +#define FOGFUNC_ENABLE (1<<31) +#define FOGFUNC_VERTEX 0 +#define FOGFUNC_PIXEL_EXP (1<<28) +#define FOGFUNC_PIXEL_EXP2 (2<<28) +#define FOGFUNC_PIXEL_LINEAR (3<<28) +#define FOGSRC_INDEX_Z (1<<27) +#define FOGSRC_INDEX_W ((1<<27)|(1<<25)) +#define FOG_LINEAR_CONST (1<<24) +#define FOG_CONST_1(x) ((x)<<4) +#define ENABLE_FOG_DENSITY (1<<23) +/* Dword 2 */ +#define FOG_CONST_2(x) (x) +/* Dword 3 */ +#define FOG_DENSITY(x) (x) + +/* STATE3D_INDEPENDENT_ALPHA_BLEND, p142 */ +#define STATE3D_INDPT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) +#define ENABLE_INDPT_ALPHA_BLEND ((1<<23)|(1<<22)) +#define DISABLE_INDPT_ALPHA_BLEND (1<<23) +#define ALPHA_BLENDFUNC_MASK 0x3f0000 +#define ENABLE_ALPHA_BLENDFUNC (1<<21) +#define ABLENDFUNC_ADD 0 +#define ABLENDFUNC_SUB (1<<16) +#define ABLENDFUNC_RVSE_SUB (2<<16) +#define ABLENDFUNC_MIN (3<<16) +#define ABLENDFUNC_MAX (4<<16) +#define SRC_DST_ABLEND_MASK 0xfff +#define ENABLE_SRC_ABLEND_FACTOR (1<<11) +#define SRC_ABLEND_FACT(x) ((x)<<6) +#define ENABLE_DST_ABLEND_FACTOR (1<<5) +#define DST_ABLEND_FACT(x) (x) + +#define BLEND_STATE_MASK (ALPHA_BLENDFUNC_MASK | SRC_DST_ABLEND_MASK) + +#define BLENDFACT_ZERO 0x01 +#define BLENDFACT_ONE 0x02 +#define BLENDFACT_SRC_COLR 0x03 +#define BLENDFACT_INV_SRC_COLR 0x04 +#define BLENDFACT_SRC_ALPHA 0x05 +#define BLENDFACT_INV_SRC_ALPHA 0x06 +#define BLENDFACT_DST_ALPHA 0x07 +#define BLENDFACT_INV_DST_ALPHA 0x08 +#define BLENDFACT_DST_COLR 0x09 +#define BLENDFACT_INV_DST_COLR 0x0a +#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b +#define BLENDFACT_CONST_COLOR 0x0c +#define BLENDFACT_INV_CONST_COLOR 0x0d +#define BLENDFACT_CONST_ALPHA 0x0e +#define BLENDFACT_INV_CONST_ALPHA 0x0f + +/* STATE3D_MAP_BLEND_ARG, p152 */ +#define STATE3D_MAP_BLEND_ARG_CMD(stage) (CMD_3D|(0x0e<<24)|((stage)<<20)) + +#define TEXPIPE_COLOR 0 +#define TEXPIPE_ALPHA (1<<18) +#define TEXPIPE_KILL (2<<18) +#define TEXBLEND_ARG0 0 +#define TEXBLEND_ARG1 (1<<15) +#define TEXBLEND_ARG2 (2<<15) +#define TEXBLEND_ARG3 (3<<15) +#define TEXBLENDARG_MODIFY_PARMS (1<<6) +#define TEXBLENDARG_REPLICATE_ALPHA (1<<5) +#define TEXBLENDARG_INV_ARG (1<<4) +#define TEXBLENDARG_ONE 0 +#define TEXBLENDARG_FACTOR 0x01 +#define TEXBLENDARG_ACCUM 0x02 +#define TEXBLENDARG_DIFFUSE 0x03 +#define TEXBLENDARG_SPEC 0x04 +#define TEXBLENDARG_CURRENT 0x05 +#define TEXBLENDARG_TEXEL0 0x06 +#define TEXBLENDARG_TEXEL1 0x07 +#define TEXBLENDARG_TEXEL2 0x08 +#define TEXBLENDARG_TEXEL3 0x09 +#define TEXBLENDARG_FACTOR_N 0x0e + +/* STATE3D_MAP_BLEND_OP, p155 */ +#define STATE3D_MAP_BLEND_OP_CMD(stage) (CMD_3D|(0x0d<<24)|((stage)<<20)) +#if 0 +#define TEXPIPE_COLOR 0 +#define TEXPIPE_ALPHA (1<<18) +#define TEXPIPE_KILL (2<<18) +#endif +#define ENABLE_TEXOUTPUT_WRT_SEL (1<<17) +#define TEXOP_OUTPUT_CURRENT 0 +#define TEXOP_OUTPUT_ACCUM (1<<15) +#define ENABLE_TEX_CNTRL_STAGE ((1<<12)|(1<<11)) +#define DISABLE_TEX_CNTRL_STAGE (1<<12) +#define TEXOP_SCALE_SHIFT 9 +#define TEXOP_SCALE_1X (0 << TEXOP_SCALE_SHIFT) +#define TEXOP_SCALE_2X (1 << TEXOP_SCALE_SHIFT) +#define TEXOP_SCALE_4X (2 << TEXOP_SCALE_SHIFT) +#define TEXOP_MODIFY_PARMS (1<<8) +#define TEXOP_LAST_STAGE (1<<7) +#define TEXBLENDOP_KILLPIXEL 0x02 +#define TEXBLENDOP_ARG1 0x01 +#define TEXBLENDOP_ARG2 0x02 +#define TEXBLENDOP_MODULATE 0x03 +#define TEXBLENDOP_ADD 0x06 +#define TEXBLENDOP_ADDSIGNED 0x07 +#define TEXBLENDOP_BLEND 0x08 +#define TEXBLENDOP_BLEND_AND_ADD 0x09 +#define TEXBLENDOP_SUBTRACT 0x0a +#define TEXBLENDOP_DOT3 0x0b +#define TEXBLENDOP_DOT4 0x0c +#define TEXBLENDOP_MODULATE_AND_ADD 0x0d +#define TEXBLENDOP_MODULATE_2X_AND_ADD 0x0e +#define TEXBLENDOP_MODULATE_4X_AND_ADD 0x0f + +/* STATE3D_MAP_BUMP_TABLE, p160 TODO */ +/* STATE3D_MAP_COLOR_CHROMA_KEY, p161 TODO */ + +/* STATE3D_MAP_COORD_SET_BINDINGS, p162 */ +#define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16)) +#define TEXBIND_MASK3 ((1<<15)|(1<<14)|(1<<13)|(1<<12)) +#define TEXBIND_MASK2 ((1<<11)|(1<<10)|(1<<9)|(1<<8)) +#define TEXBIND_MASK1 ((1<<7)|(1<<6)|(1<<5)|(1<<4)) +#define TEXBIND_MASK0 ((1<<3)|(1<<2)|(1<<1)|1) + +#define TEXBIND_SET3(x) ((x)<<12) +#define TEXBIND_SET2(x) ((x)<<8) +#define TEXBIND_SET1(x) ((x)<<4) +#define TEXBIND_SET0(x) (x) + +#define TEXCOORDSRC_KEEP 0 +#define TEXCOORDSRC_DEFAULT 0x01 +#define TEXCOORDSRC_VTXSET_0 0x08 +#define TEXCOORDSRC_VTXSET_1 0x09 +#define TEXCOORDSRC_VTXSET_2 0x0a +#define TEXCOORDSRC_VTXSET_3 0x0b +#define TEXCOORDSRC_VTXSET_4 0x0c +#define TEXCOORDSRC_VTXSET_5 0x0d +#define TEXCOORDSRC_VTXSET_6 0x0e +#define TEXCOORDSRC_VTXSET_7 0x0f + +#define MAP_UNIT(unit) ((unit)<<16) +#define MAP_UNIT_MASK (3<<16) + +/* STATE3D_MAP_COORD_SETS, p164 */ +#define STATE3D_MAP_COORD_SET_CMD (CMD_3D|(0x1c<<24)|(0x01<<19)) +#define ENABLE_TEXCOORD_PARAMS (1<<15) +#define TEXCOORDS_ARE_NORMAL (1<<14) +#define TEXCOORDS_ARE_IN_TEXELUNITS 0 +#define TEXCOORDTYPE_CARTESIAN 0 +#define TEXCOORDTYPE_HOMOGENEOUS (1<<11) +#define TEXCOORDTYPE_VECTOR (2<<11) +#define ENABLE_ADDR_V_CNTL (1<<7) +#define ENABLE_ADDR_U_CNTL (1<<3) +#define TEXCOORD_ADDR_V_MODE(x) ((x)<<4) +#define TEXCOORD_ADDR_U_MODE(x) (x) +#define TEXCOORDMODE_WRAP 0 +#define TEXCOORDMODE_MIRROR 1 +#define TEXCOORDMODE_CLAMP 2 +#define TEXCOORDMODE_WRAP_SHORTEST 3 +#define TEXCOORDMODE_CLAMP_BORDER 4 +#define TEXCOORD_ADDR_V_MASK 0x70 +#define TEXCOORD_ADDR_U_MASK 0x7 + +/* STATE3D_MAP_CUBE, p168 TODO */ +#define STATE3D_MAP_CUBE (CMD_3D|(0x1c<<24)|(0x0a<<19)) +#define CUBE_NEGX_ENABLE (1<<5) +#define CUBE_POSX_ENABLE (1<<4) +#define CUBE_NEGY_ENABLE (1<<3) +#define CUBE_POSY_ENABLE (1<<2) +#define CUBE_NEGZ_ENABLE (1<<1) +#define CUBE_POSZ_ENABLE (1<<0) + + +/* STATE3D_MODES_1, p190 */ +#define STATE3D_MODES_1_CMD (CMD_3D|(0x08<<24)) +#define BLENDFUNC_MASK 0x3f0000 +#define ENABLE_COLR_BLND_FUNC (1<<21) +#define BLENDFUNC_ADD 0 +#define BLENDFUNC_SUB (1<<16) +#define BLENDFUNC_RVRSE_SUB (2<<16) +#define BLENDFUNC_MIN (3<<16) +#define BLENDFUNC_MAX (4<<16) +#define SRC_DST_BLND_MASK 0xfff +#define ENABLE_SRC_BLND_FACTOR (1<<11) +#define ENABLE_DST_BLND_FACTOR (1<<5) +#define SRC_BLND_FACT(x) ((x)<<6) +#define DST_BLND_FACT(x) (x) + +/* Use the blendfact defines for BLND_FACTOR macros */ +#if 0 +#define BLENDFACT_ZERO 0x01 +#define BLENDFACT_ONE 0x02 +#define BLENDFACT_SRC_COLR 0x03 +#define BLENDFACT_INV_SRC_COLR 0x04 +#define BLENDFACT_SRC_ALPHA 0x05 +#define BLENDFACT_INV_SRC_ALPHA 0x06 +#define BLENDFACT_DST_ALPHA 0x07 +#define BLENDFACT_INV_DST_ALPHA 0x08 +#define BLENDFACT_CONST_ALPHA 0x0e +#define BLENDFACT_INV_CONST_ALPHA 0x0f +#endif + +/* STATE3D_MODES_2, p192 */ +#define STATE3D_MODES_2_CMD (CMD_3D|(0x0f<<24)) +#define ENABLE_GLOBAL_DEPTH_BIAS (1<<22) +#define GLOBAL_DEPTH_BIAS(x) ((x)<<14) +#define ENABLE_ALPHA_TEST_FUNC (1<<13) +#define ENABLE_ALPHA_REF_VALUE (1<<8) +#define ALPHA_TEST_FUNC(x) ((x)<<9) +#define ALPHA_REF_VALUE(x) (x) + +#define ALPHA_TEST_REF_MASK 0x3fff +#define COMPAREFUNC_ALWAYS 0 +#define COMPAREFUNC_NEVER 0x1 +#define COMPAREFUNC_LESS 0x2 +#define COMPAREFUNC_EQUAL 0x3 +#define COMPAREFUNC_LEQUAL 0x4 +#define COMPAREFUNC_GREATER 0x5 +#define COMPAREFUNC_NOTEQUAL 0x6 +#define COMPAREFUNC_GEQUAL 0x7 + +/* STATE3D_MODES_3, p193 */ +#define STATE3D_MODES_3_CMD (CMD_3D|(0x02<<24)) +#define DEPTH_TEST_FUNC_MASK 0x1f0000 +#define ENABLE_DEPTH_TEST_FUNC (1<<20) +/* Uses COMPAREFUNC */ +#define DEPTH_TEST_FUNC(x) ((x)<<16) +#define ENABLE_ALPHA_SHADE_MODE (1<<11) +#define ENABLE_FOG_SHADE_MODE (1<<9) +#define ENABLE_SPEC_SHADE_MODE (1<<7) +#define ENABLE_COLOR_SHADE_MODE (1<<5) +#define ALPHA_SHADE_MODE(x) ((x)<<10) +#define FOG_SHADE_MODE(x) ((x)<<8) +#define SPEC_SHADE_MODE(x) ((x)<<6) +#define COLOR_SHADE_MODE(x) ((x)<<4) +#define CULLMODE_MASK 0xf +#define ENABLE_CULL_MODE (1<<3) +#define CULLMODE_BOTH 0 +#define CULLMODE_NONE 1 +#define CULLMODE_CW 2 +#define CULLMODE_CCW 3 + +#define SHADE_MODE_LINEAR 0 +#define SHADE_MODE_FLAT 0x1 + +/* STATE3D_MODES_4, p195 */ +#define STATE3D_MODES_4_CMD (CMD_3D|(0x16<<24)) +#define ENABLE_LOGIC_OP_FUNC (1<<23) +#define LOGIC_OP_FUNC(x) ((x)<<18) +#define LOGICOP_MASK ((1<<18)|(1<<19)|(1<<20)|(1<<21)) +#define LOGICOP_CLEAR 0 +#define LOGICOP_NOR 0x1 +#define LOGICOP_AND_INV 0x2 +#define LOGICOP_COPY_INV 0x3 +#define LOGICOP_AND_RVRSE 0x4 +#define LOGICOP_INV 0x5 +#define LOGICOP_XOR 0x6 +#define LOGICOP_NAND 0x7 +#define LOGICOP_AND 0x8 +#define LOGICOP_EQUIV 0x9 +#define LOGICOP_NOOP 0xa +#define LOGICOP_OR_INV 0xb +#define LOGICOP_COPY 0xc +#define LOGICOP_OR_RVRSE 0xd +#define LOGICOP_OR 0xe +#define LOGICOP_SET 0xf +#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) +#define ENABLE_STENCIL_TEST_MASK (1<<17) +#define STENCIL_TEST_MASK(x) ((x)<<8) +#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) +#define ENABLE_STENCIL_WRITE_MASK (1<<16) +#define STENCIL_WRITE_MASK(x) (x) + +/* STATE3D_MODES_5, p196 */ +#define STATE3D_MODES_5_CMD (CMD_3D|(0x0c<<24)) +#define ENABLE_SPRITE_POINT_TEX (1<<23) +#define SPRITE_POINT_TEX_ON (1<<22) +#define SPRITE_POINT_TEX_OFF 0 +#define FLUSH_RENDER_CACHE (1<<18) +#define FLUSH_TEXTURE_CACHE (1<<16) +#define FIXED_LINE_WIDTH_MASK 0xfc00 +#define ENABLE_FIXED_LINE_WIDTH (1<<15) +#define FIXED_LINE_WIDTH(x) ((x)<<10) +#define FIXED_POINT_WIDTH_MASK 0x3ff +#define ENABLE_FIXED_POINT_WIDTH (1<<9) +#define FIXED_POINT_WIDTH(x) (x) + +/* STATE3D_RASTERIZATION_RULES, p198 */ +#define STATE3D_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) +#define ENABLE_POINT_RASTER_RULE (1<<15) +#define OGL_POINT_RASTER_RULE (1<<13) +#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) +#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) +#define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2) +#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) +#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) +#define TRI_STRIP_PROVOKE_VRTX(x) (x) + +/* STATE3D_SCISSOR_ENABLE, p200 */ +#define STATE3D_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) +#define ENABLE_SCISSOR_RECT ((1<<1) | 1) +#define DISABLE_SCISSOR_RECT (1<<1) + +/* STATE3D_SCISSOR_RECTANGLE_0, p201 */ +#define STATE3D_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) +/* Dword 1 */ +#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) +#define SCISSOR_RECT_0_XMIN(x) (x) +/* Dword 2 */ +#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) +#define SCISSOR_RECT_0_XMAX(x) (x) + +/* STATE3D_STENCIL_TEST, p202 */ +#define STATE3D_STENCIL_TEST_CMD (CMD_3D|(0x09<<24)) +#define ENABLE_STENCIL_PARMS (1<<23) +#define STENCIL_OPS_MASK (0xffc000) +#define STENCIL_FAIL_OP(x) ((x)<<20) +#define STENCIL_PASS_DEPTH_FAIL_OP(x) ((x)<<17) +#define STENCIL_PASS_DEPTH_PASS_OP(x) ((x)<<14) + +#define STENCILOP_KEEP 0 +#define STENCILOP_ZERO 0x1 +#define STENCILOP_REPLACE 0x2 +#define STENCILOP_INCRSAT 0x3 +#define STENCILOP_DECRSAT 0x4 +#define STENCILOP_INCR 0x5 +#define STENCILOP_DECR 0x6 +#define STENCILOP_INVERT 0x7 + +#define ENABLE_STENCIL_TEST_FUNC_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)) +#define ENABLE_STENCIL_TEST_FUNC (1<<13) +/* Uses COMPAREFUNC */ +#define STENCIL_TEST_FUNC(x) ((x)<<9) +#define STENCIL_REF_VALUE_MASK ((1<<8)|0xff) +#define ENABLE_STENCIL_REF_VALUE (1<<8) +#define STENCIL_REF_VALUE(x) (x) + +/* STATE3D_VERTEX_FORMAT, p204 */ +#define STATE3D_VERTEX_FORMAT_CMD (CMD_3D|(0x05<<24)) +#define VRTX_HAS_POINT_WIDTH (1<<12) +#define VRTX_TEX_COORD_COUNT(x) ((x)<<8) +#define VRTX_HAS_SPEC (1<<7) +#define VRTX_HAS_DIFFUSE (1<<6) +#define VRTX_HAS_DEPTH_OFS (1<<5) +#define VRTX_HAS_XYZ (1<<1) +#define VRTX_HAS_XYZW (2<<1) +#define VRTX_HAS_XY (3<<1) +#define VRTX_HAS_XYW (4<<1) + +/* STATE3D_VERTEX_FORMAT_2, p206 */ +#define STATE3D_VERTEX_FORMAT_2_CMD (CMD_3D|(0x0a<<24)) +#define VRTX_TEX_SET_7_FMT(x) ((x)<<14) +#define VRTX_TEX_SET_6_FMT(x) ((x)<<12) +#define VRTX_TEX_SET_5_FMT(x) ((x)<<10) +#define VRTX_TEX_SET_4_FMT(x) ((x)<<8) +#define VRTX_TEX_SET_3_FMT(x) ((x)<<6) +#define VRTX_TEX_SET_2_FMT(x) ((x)<<4) +#define VRTX_TEX_SET_1_FMT(x) ((x)<<2) +#define VRTX_TEX_SET_0_FMT(x) (x) + +#define TEXCOORDFMT_2D 0 +#define TEXCOORDFMT_3D 1 +#define TEXCOORDFMT_4D 2 +#define TEXCOORDFMT_1D 3 + +/*New stuff picked up along the way */ + +#define MLC_LOD_BIAS_MASK ((1<<7)-1) + + +/* STATE3D_VERTEX_TRANSFORM, p207 */ +#define STATE3D_VERTEX_TRANS_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|0) +#define STATE3D_VERTEX_TRANS_MTX_CMD (CMD_3D|(0x1d<<24)|(0x8b<<16)|6) +/* Dword 1 */ +#define ENABLE_VIEWPORT_TRANSFORM ((1<<31)|(1<<30)) +#define DISABLE_VIEWPORT_TRANSFORM (1<<31) +#define ENABLE_PERSP_DIVIDE ((1<<29)|(1<<28)) +#define DISABLE_PERSP_DIVIDE (1<<29) +#define VRTX_TRANS_LOAD_MATRICES 0x7421 +#define VRTX_TRANS_NO_LOAD_MATRICES 0x0000 +/* Dword 2 -> 7 are matrix elements */ + +/* STATE3D_W_STATE, p209 */ +#define STATE3D_W_STATE_CMD (CMD_3D|(0x1d<<24)|(0x8d<<16)|1) +/* Dword 1 */ +#define MAGIC_W_STATE_DWORD1 0x00000008 +/* Dword 2 */ +#define WFAR_VALUE(x) (x) + +/* if defining I830_ENABLE_4_TEXTURES, do it in i830_drm.h, too */ + +#define I830PACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +#define I830PACKCOLOR1555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define I830PACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define I830PACKCOLOR8888(r,g,b,a) \ + ((a<<24) | (r<<16) | (g<<8) | b) + + +/* Stipple command, carried over from the i810, apparently: + */ +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define ST1_ENABLE (1<<16) +#define ST1_MASK (0xffff) + + + +#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16)) +#define LOAD_TEXTURE_MAP0 (1<<11) + +#define TM0S0_ADDRESS_MASK 0xfffffffc +#define TM0S0_USE_FENCE (1<<1) + +#define TM0S1_HEIGHT_SHIFT 21 +#define TM0S1_WIDTH_SHIFT 10 +#define TM0S1_PALETTE_SELECT (1<<9) +#define TM0S1_MAPSURF_FORMAT_MASK (0x7 << 6) +#define TM0S1_MAPSURF_FORMAT_SHIFT 6 +#define MAPSURF_8BIT_INDEXED (0<<6) +#define MAPSURF_8BIT (1<<6) +#define MAPSURF_16BIT (2<<6) +#define MAPSURF_32BIT (3<<6) +#define MAPSURF_411 (4<<6) +#define MAPSURF_422 (5<<6) +#define MAPSURF_COMPRESSED (6<<6) +#define MAPSURF_4BIT_INDEXED (7<<6) +#define TM0S1_MT_FORMAT_MASK (0x7 << 3) +#define TM0S1_MT_FORMAT_SHIFT 3 +#define MT_4BIT_IDX_ARGB8888 (7<<3) /* SURFACE_4BIT_INDEXED */ +#define MT_8BIT_IDX_RGB565 (0<<3) /* SURFACE_8BIT_INDEXED */ +#define MT_8BIT_IDX_ARGB1555 (1<<3) +#define MT_8BIT_IDX_ARGB4444 (2<<3) +#define MT_8BIT_IDX_AY88 (3<<3) +#define MT_8BIT_IDX_ABGR8888 (4<<3) +#define MT_8BIT_IDX_BUMP_88DVDU (5<<3) +#define MT_8BIT_IDX_BUMP_655LDVDU (6<<3) +#define MT_8BIT_IDX_ARGB8888 (7<<3) +#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ +#define MT_8BIT_L8 (1<<3) +#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ +#define MT_16BIT_ARGB1555 (1<<3) +#define MT_16BIT_ARGB4444 (2<<3) +#define MT_16BIT_AY88 (3<<3) +#define MT_16BIT_DIB_ARGB1555_8888 (4<<3) +#define MT_16BIT_BUMP_88DVDU (5<<3) +#define MT_16BIT_BUMP_655LDVDU (6<<3) +#define MT_16BIT_DIB_RGB565_8888 (7<<3) +#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ +#define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) +#define MT_32BIT_DIB_8888 (7<<3) +#define MT_411_YUV411 (0<<3) /* SURFACE_411 */ +#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ +#define MT_422_YCRCB_NORMAL (1<<3) +#define MT_422_YCRCB_SWAPUV (2<<3) +#define MT_422_YCRCB_SWAPUVY (3<<3) +#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ +#define MT_COMPRESS_DXT2_3 (1<<3) +#define MT_COMPRESS_DXT4_5 (2<<3) +#define MT_COMPRESS_FXT1 (3<<3) +#define TM0S1_COLORSPACE_CONVERSION (1 << 2) +#define TM0S1_TILED_SURFACE (1 << 1) +#define TM0S1_TILE_WALK (1 << 0) + +#define TM0S2_PITCH_SHIFT 21 +#define TM0S2_CUBE_FACE_ENA_SHIFT 15 +#define TM0S2_MAP_FORMAT (1<<14) +#define TM0S2_VERTICAL_LINE_STRIDE (1<<13) +#define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) +#define TM0S2_OUTPUT_CHAN_SHIFT 10 +#define TM0S2_OUTPUT_CHAN_MASK (3<<10) + +#define TM0S3_MIP_FILTER_MASK (0x3<<30) +#define TM0S3_MIP_FILTER_SHIFT 30 +#define MIPFILTER_NONE 0 +#define MIPFILTER_NEAREST 1 +#define MIPFILTER_LINEAR 3 +#define TM0S3_MAG_FILTER_MASK (0x3<<28) +#define TM0S3_MAG_FILTER_SHIFT 28 +#define TM0S3_MIN_FILTER_MASK (0x3<<26) +#define TM0S3_MIN_FILTER_SHIFT 26 +#define FILTER_NEAREST 0 +#define FILTER_LINEAR 1 +#define FILTER_ANISOTROPIC 2 + +#define TM0S3_LOD_BIAS_SHIFT 17 +#define TM0S3_LOD_BIAS_MASK (0x1ff<<17) +#define TM0S3_MAX_MIP_SHIFT 9 +#define TM0S3_MAX_MIP_MASK (0xff<<9) +#define TM0S3_MIN_MIP_SHIFT 3 +#define TM0S3_MIN_MIP_MASK (0x3f<<3) +#define TM0S3_KILL_PIXEL (1<<2) +#define TM0S3_KEYED_FILTER (1<<1) +#define TM0S3_CHROMA_KEY (1<<0) + + +/* STATE3D_MAP_TEXEL_STREAM, p188 */ +#define STATE3D_MAP_TEX_STREAM_CMD (CMD_3D|(0x1c<<24)|(0x05<<19)) +#define DISABLE_TEX_STREAM_BUMP (1<<12) +#define ENABLE_TEX_STREAM_BUMP ((1<<12)|(1<<11)) +#define TEX_MODIFY_UNIT_0 0 +#define TEX_MODIFY_UNIT_1 (1<<8) +#define ENABLE_TEX_STREAM_COORD_SET (1<<7) +#define TEX_STREAM_COORD_SET(x) ((x)<<4) +#define ENABLE_TEX_STREAM_MAP_IDX (1<<3) +#define TEX_STREAM_MAP_IDX(x) (x) diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_context.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_context.c new file mode 100644 index 000000000..45fcbd2e3 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_context.c @@ -0,0 +1,626 @@ +/************************************************************************** + * + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_context.c,v 1.9 2003/02/06 04:18:00 dawes Exp $ */ + +/** + * \file i830_context.c + * + * Heavily Based on I810 driver written by Keith Whitwell. + * + * \author Jeff Hartmann <jhartmann@2d3d.com> + * \author Graeme Fisher <graeme@2d3d.co.za> + * \author Abraham vd Merwe <abraham@2d3d.co.za> + * \author Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "glheader.h" +#include "context.h" +#include "matrix.h" +#include "simple_list.h" +#include "extensions.h" +#include "framebuffer.h" +#include "imports.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "array_cache/acache.h" + +#include "tnl/t_pipeline.h" + +#include "drivers/common/driverfuncs.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_state.h" +#include "i830_tex.h" +#include "i830_span.h" +#include "i830_tris.h" +#include "i830_ioctl.h" + + +#include "utils.h" + +#define need_GL_ARB_multisample +#define need_GL_ARB_texture_compression +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_fog_coord +#define need_GL_EXT_secondary_color +#include "extension_helper.h" + +#include "xmlpool.h" /* for symbolic values of enum-type options */ +#ifndef I830_DEBUG +int I830_DEBUG = (0); +#endif + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + +#define DRIVER_DATE "20041007" + + +static const GLubyte *i830DDGetString( GLcontext *ctx, GLenum name ) +{ + const char * chipset; + static char buffer[128]; + + switch (name) { + case GL_VENDOR: + switch (I830_CONTEXT(ctx)->i830Screen->deviceID) { + case PCI_CHIP_845_G: + return (GLubyte *)"2d3D, Inc"; + + case PCI_CHIP_I830_M: + return (GLubyte *)"VA Linux, Inc"; + + case PCI_CHIP_I855_GM: + case PCI_CHIP_I865_G: + default: + return (GLubyte *)"Tungsten Graphics, Inc"; + } + break; + + case GL_RENDERER: + switch (I830_CONTEXT(ctx)->i830Screen->deviceID) { + case PCI_CHIP_845_G: + chipset = "Intel(R) 845G"; break; + case PCI_CHIP_I830_M: + chipset = "Intel(R) 830M"; break; + case PCI_CHIP_I855_GM: + chipset = "Intel(R) 852GM/855GM"; break; + case PCI_CHIP_I865_G: + chipset = "Intel(R) 865G"; break; + default: + chipset = "Unknown Intel Chipset"; break; + } + + (void) driGetRendererString( buffer, chipset, DRIVER_DATE, 0 ); + return (GLubyte *) buffer; + + default: + return NULL; + } +} + +static void i830BufferSize(GLframebuffer *buffer, + GLuint *width, GLuint *height) +{ + GET_CURRENT_CONTEXT(ctx); + i830ContextPtr imesa = I830_CONTEXT(ctx); + /* Need to lock to make sure the driDrawable is uptodate. This + * information is used to resize Mesa's software buffers, so it has + * to be correct. + */ + LOCK_HARDWARE(imesa); + *width = imesa->driDrawable->w; + *height = imesa->driDrawable->h; + UNLOCK_HARDWARE(imesa); +} + + +/* Extension strings exported by the i830 driver. + */ +const struct dri_extension card_extensions[] = +{ + { "GL_ARB_multisample", GL_ARB_multisample_functions }, + { "GL_ARB_multitexture", NULL }, + { "GL_ARB_texture_border_clamp", NULL }, + { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, + { "GL_ARB_texture_env_add", NULL }, + { "GL_ARB_texture_env_combine", NULL }, + { "GL_ARB_texture_env_crossbar", NULL }, + { "GL_ARB_texture_env_dot3", NULL }, + { "GL_ARB_texture_mirrored_repeat", NULL }, + { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, + { "GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions }, + { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions }, + { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions }, + { "GL_EXT_blend_subtract", NULL }, + { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, + { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, + { "GL_EXT_stencil_wrap", NULL }, + { "GL_EXT_texture_edge_clamp", NULL }, + { "GL_EXT_texture_env_combine", NULL }, + { "GL_EXT_texture_env_dot3", NULL }, + { "GL_EXT_texture_filter_anisotropic", NULL }, + { "GL_EXT_texture_lod_bias", NULL }, + { "GL_EXT_texture_rectangle", NULL }, + { "GL_MESA_ycbcr_texture", NULL }, + { "GL_NV_blend_square", NULL }, + { "GL_SGIS_generate_mipmap", NULL }, + { NULL, NULL } +}; + + +extern const struct tnl_pipeline_stage _i830_render_stage; + +static const struct tnl_pipeline_stage *i830_pipeline[] = { + &_tnl_vertex_transform_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + /* REMOVE: point attenuation stage */ +#if 1 + &_i830_render_stage, /* ADD: unclipped rastersetup-to-dma */ +#endif + &_tnl_render_stage, + 0, +}; + + +static const struct dri_debug_control debug_control[] = +{ + { "fall", DEBUG_FALLBACKS }, + { "tex", DEBUG_TEXTURE }, + { "ioctl", DEBUG_IOCTL }, + { "prim", DEBUG_PRIMS }, + { "vert", DEBUG_VERTS }, + { "state", DEBUG_STATE }, + { "verb", DEBUG_VERBOSE }, + { "dri", DEBUG_DRI }, + { "dma", DEBUG_DMA }, + { "san", DEBUG_SANITY }, + { "sync", DEBUG_SYNC }, + { "sleep", DEBUG_SLEEP }, + { NULL, 0 } +}; + + +GLboolean i830CreateContext( const __GLcontextModes *mesaVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate) +{ + GLcontext *ctx , *shareCtx; + i830ContextPtr imesa; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + i830ScreenPrivate *screen = (i830ScreenPrivate *)sPriv->private; + I830SAREAPtr saPriv=(I830SAREAPtr) + (((GLubyte *)sPriv->pSAREA)+screen->sarea_priv_offset); + struct dd_function_table functions; + + /* Allocate i830 context */ + imesa = (i830ContextPtr) CALLOC_STRUCT(i830_context_t); + if (!imesa) + return GL_FALSE; + + /* Init default driver functions then plug in our I830-specific functions + * (the texture functions are especially important) + */ + _mesa_init_driver_functions(&functions); + i830InitIoctlFuncs(&functions); + i830InitTextureFuncs(&functions); + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((i830ContextPtr) sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + imesa->glCtx = _mesa_create_context(mesaVis, shareCtx, + &functions, (void*) imesa); + if (!imesa->glCtx) { + FREE(imesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = imesa; + + + imesa->i830Screen = screen; + imesa->driScreen = sPriv; + imesa->sarea = saPriv; + imesa->glBuffer = NULL; + + driParseConfigFiles (&imesa->optionCache, &screen->optionCache, + screen->driScrnPriv->myNum, "i830"); + + (void) memset( imesa->texture_heaps, 0, sizeof( imesa->texture_heaps ) ); + make_empty_list( & imesa->swapped ); + + imesa->nr_heaps = 1; + imesa->texture_heaps[0] = driCreateTextureHeap( 0, imesa, + screen->textureSize, + 12, + I830_NR_TEX_REGIONS, + imesa->sarea->texList, + (unsigned *) & imesa->sarea->texAge, /* XXX shouldn't need cast! */ + & imesa->swapped, + sizeof( struct i830_texture_object_t ), + (destroy_texture_object_t *) i830DestroyTexObj ); + + /* Set the maximum texture size small enough that we can guarantee + * that every texture unit can bind a maximal texture and have them + * in memory at once. + */ + + ctx = imesa->glCtx; + ctx->Const.MaxTextureUnits = driQueryOptioni(&imesa->optionCache, + "texture_units"); + ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; + + /* FIXME: driCalculateMaxTextureLevels assumes that mipmaps are tightly + * FIXME: packed, but they're not in Intel graphics hardware. + */ + driCalculateMaxTextureLevels( imesa->texture_heaps, + imesa->nr_heaps, + & ctx->Const, + 4, + 11, /* max 2D texture size is 2048x2048 */ + 0, /* 3D textures unsupported */ + 0, /* cube textures unsupported. */ + 0, /* texture rectangles unsupported. */ + 12, + GL_FALSE ); + + ctx->Const.MaxTextureMaxAnisotropy = 2.0; + + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = 3.0; + ctx->Const.MaxLineWidthAA = 3.0; + ctx->Const.LineWidthGranularity = 1.0; + + ctx->Const.MinPointSize = 1.0; + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSize = 255.0; + ctx->Const.MaxPointSizeAA = 3.0; + ctx->Const.PointSizeGranularity = 1.0; + + ctx->Driver.GetBufferSize = i830BufferSize; + ctx->Driver.ResizeBuffers = _mesa_resize_framebuffer; + ctx->Driver.GetString = i830DDGetString; + + /* Who owns who? */ + ctx->DriverCtx = (void *) imesa; + imesa->glCtx = ctx; + + /* Initialize the software rasterizer and helper modules. */ + _swrast_CreateContext( ctx ); + _ac_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + _swsetup_CreateContext( ctx ); + + /* Install the customized pipeline: */ + _tnl_destroy_pipeline( ctx ); + _tnl_install_pipeline( ctx, i830_pipeline ); + + /* Configure swrast and T&L to match hardware characteristics: */ + _swrast_allow_pixel_fog( ctx, GL_FALSE ); + _swrast_allow_vertex_fog( ctx, GL_TRUE ); + _tnl_allow_pixel_fog( ctx, GL_FALSE ); + _tnl_allow_vertex_fog( ctx, GL_TRUE ); + + /* Dri stuff */ + imesa->hHWContext = driContextPriv->hHWContext; + imesa->driFd = sPriv->fd; + /* drmLock ptr = &drm_hw_lock_t */ + imesa->driHwLock = (drmLock *) &sPriv->pSAREA->lock; + imesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24; + + switch(mesaVis->depthBits) { + case 16: + imesa->depth_scale = 1.0/0xffff; + imesa->depth_clear_mask = ~0; + imesa->ClearDepth = 0xffff; + break; + case 24: + imesa->depth_scale = 1.0/0xffffff; + imesa->depth_clear_mask = 0x00ffffff; + imesa->stencil_clear_mask = 0xff000000; + imesa->ClearDepth = 0x00ffffff; + break; + case 32: /* Not supported */ + default: + break; + } + /* Completely disable stenciling for now, there are some serious issues + * with stencil. + */ +#if 0 + imesa->hw_stencil = 0; +#endif + + imesa->RenderIndex = ~0; + imesa->dirty = ~0; + imesa->upload_cliprects = GL_TRUE; + + imesa->CurrentTexObj[0] = 0; + imesa->CurrentTexObj[1] = 0; + + imesa->do_irqs = (imesa->i830Screen->irq_active && + !getenv("I830_NO_IRQS")); + + _math_matrix_ctr (&imesa->ViewportMatrix); + + driInitExtensions( ctx, card_extensions, GL_TRUE ); + + if (imesa->glCtx->Mesa_DXTn) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + _mesa_enable_extension( ctx, "GL_S3_s3tc" ); + } + else if (driQueryOptionb (&imesa->optionCache, "force_s3tc_enable")) { + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + } + + _mesa_enable_extension( ctx, "GL_3DFX_texture_compression_FXT1" ); + + /* XXX these should really go right after _mesa_init_driver_functions() */ + i830DDInitStateFuncs( ctx ); + i830InitTriFuncs (ctx); + i830DDInitSpanFuncs( ctx ); + i830DDInitState (ctx); + +#if DO_DEBUG + I830_DEBUG = driParseDebugString( getenv( "I830_DEBUG" ), + debug_control ); + I830_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ), + debug_control ); +#endif + + if (getenv("I830_NO_RAST") || + getenv("INTEL_NO_RAST")) { + fprintf(stderr, "disabling 3D rasterization\n"); + FALLBACK(imesa, I830_FALLBACK_USER, 1); + } + + return GL_TRUE; +} + +void i830DestroyContext(__DRIcontextPrivate *driContextPriv) +{ + i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate; + + assert(imesa); /* should never be null */ + if (imesa) { + GLboolean release_texture_heaps; + + + release_texture_heaps = (imesa->glCtx->Shared->RefCount == 1); + _swsetup_DestroyContext (imesa->glCtx); + _tnl_DestroyContext (imesa->glCtx); + _ac_DestroyContext (imesa->glCtx); + _swrast_DestroyContext (imesa->glCtx); + + /* free the Mesa context */ + imesa->glCtx->DriverCtx = NULL; + _mesa_destroy_context(imesa->glCtx); + + if ( release_texture_heaps ) { + /* This share group is about to go away, free our private + * texture object data. + */ + int i; + + for ( i = 0 ; i < imesa->nr_heaps ; i++ ) { + driDestroyTextureHeap( imesa->texture_heaps[ i ] ); + imesa->texture_heaps[ i ] = NULL; + } + + assert( is_empty_list( & imesa->swapped ) ); + } + + FREE(imesa); + } +} + +void i830XMesaSetFrontClipRects( i830ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + + imesa->numClipRects = dPriv->numClipRects; + imesa->pClipRects = dPriv->pClipRects; + imesa->drawX = dPriv->x; + imesa->drawY = dPriv->y; + + i830EmitDrawingRectangle( imesa ); + imesa->upload_cliprects = GL_TRUE; +} + +void i830XMesaSetBackClipRects( i830ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + + if (imesa->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) { + imesa->numClipRects = dPriv->numClipRects; + imesa->pClipRects = dPriv->pClipRects; + imesa->drawX = dPriv->x; + imesa->drawY = dPriv->y; + } else { + imesa->numClipRects = dPriv->numBackClipRects; + imesa->pClipRects = dPriv->pBackClipRects; + imesa->drawX = dPriv->backX; + imesa->drawY = dPriv->backY; + } + + i830EmitDrawingRectangle( imesa ); + imesa->upload_cliprects = GL_TRUE; +} + +static void i830XMesaWindowMoved( i830ContextPtr imesa ) +{ + switch (imesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]) { + case BUFFER_BIT_FRONT_LEFT: + i830XMesaSetFrontClipRects( imesa ); + break; + case BUFFER_BIT_BACK_LEFT: + i830XMesaSetBackClipRects( imesa ); + break; + default: + /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */ + i830XMesaSetFrontClipRects( imesa ); + } +} + +GLboolean i830UnbindContext(__DRIcontextPrivate *driContextPriv) +{ + i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate; + unsigned i; + + if (imesa) { + /* Might want to change this so texblend isn't always updated */ + imesa->dirty |= (I830_UPLOAD_CTX | + I830_UPLOAD_BUFFERS | + I830_UPLOAD_STIPPLE | + I830_UPLOAD_TEXBLEND0 | + I830_UPLOAD_TEXBLEND1 | + I830_UPLOAD_TEXBLEND2 | + I830_UPLOAD_TEXBLEND3); + + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if (imesa->CurrentTexObj[i]) imesa->dirty |= I830_UPLOAD_TEX_N( i ); + } + } + return GL_TRUE; +} + +GLboolean i830MakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + + if (driContextPriv) { + i830ContextPtr imesa = (i830ContextPtr) driContextPriv->driverPrivate; + + if ( imesa->driDrawable != driDrawPriv ) { + imesa->driDrawable = driDrawPriv; + i830XMesaWindowMoved( imesa ); + imesa->mesa_drawable = driDrawPriv; + } + + imesa->driReadable = driReadPriv; + + _mesa_make_current(imesa->glCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate); + } else { + _mesa_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} + +void i830GetLock( i830ContextPtr imesa, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + __DRIscreenPrivate *sPriv = imesa->driScreen; + I830SAREAPtr sarea = imesa->sarea; + int me = imesa->hHWContext; + unsigned i; + + drmGetLock(imesa->driFd, imesa->hHWContext, flags); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv); + + /* If we lost context, need to dump all registers to hardware. + * Note that we don't care about 2d contexts, even if they perform + * accelerated commands, so the DRI locking in the X server is even + * more broken than usual. + */ + + if (sarea->ctxOwner != me) { + imesa->upload_cliprects = GL_TRUE; + imesa->dirty |= (I830_UPLOAD_CTX | + I830_UPLOAD_BUFFERS | + I830_UPLOAD_STIPPLE); + + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if(imesa->CurrentTexObj[i]) imesa->dirty |= I830_UPLOAD_TEX_N( i ); + if(imesa->TexBlendWordsUsed[i]) imesa->dirty |= I830_UPLOAD_TEXBLEND_N( i ); + } + + sarea->perf_boxes = imesa->perf_boxes | I830_BOX_LOST_CONTEXT; + sarea->ctxOwner = me; + } + + /* Shared texture managment - if another client has played with + * texture space, figure out which if any of our textures have been + * ejected, and update our global LRU. + */ + + for ( i = 0 ; i < imesa->nr_heaps ; i++ ) { + DRI_AGE_TEXTURES( imesa->texture_heaps[ i ] ); + } + + if (imesa->lastStamp != dPriv->lastStamp) { + i830XMesaWindowMoved( imesa ); + imesa->lastStamp = dPriv->lastStamp; + } + + sarea->last_quiescent = -1; /* just kill it for now */ +} + +void i830SwapBuffers( __DRIdrawablePrivate *dPriv ) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + i830ContextPtr imesa; + GLcontext *ctx; + imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate; + ctx = imesa->glCtx; + if (ctx->Visual.doubleBufferMode) { + _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ + if ( 0 /*imesa->doPageFlip*/ ) { /* doPageFlip is never set !!! */ + i830PageFlip( dPriv ); + } else { + i830CopyBuffer( dPriv ); + } + } + } else { + /* XXX this shouldn't be an error but we can't handle it for now */ + _mesa_problem(NULL, "%s: drawable has no context!\n", __FUNCTION__); + } +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_context.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_context.h new file mode 100644 index 000000000..de141bd4a --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_context.h @@ -0,0 +1,327 @@ +/* + * GLX Hardware Device Driver for Intel i830 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/* Adapted for use in the I830M driver: + * Jeff Hartmann <jhartmann@2d3d.com> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_context.h,v 1.7 2003/02/06 04:18:01 dawes Exp $ */ + +#ifndef I830CONTEXT_INC +#define I830CONTEXT_INC + +typedef struct i830_context_t i830Context; +typedef struct i830_context_t *i830ContextPtr; +typedef struct i830_texture_object_t *i830TextureObjectPtr; + + +#include "mtypes.h" +#include "drm.h" +#include "mm.h" +#include "tnl/t_vertex.h" + +#include "i830_screen.h" +#include "i830_tex.h" + +#define TAG(x) i830##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +#define DV_PF_555 (1<<8) +#define DV_PF_565 (2<<8) +#define DV_PF_8888 (3<<8) + +#define I830_TEX_MAXLEVELS 10 + +#define I830_CONTEXT(ctx) ((i830ContextPtr)(ctx->DriverCtx)) +#define GET_DISPATCH_AGE(imesa) imesa->sarea->last_dispatch +#define GET_ENQUEUE_AGE(imesa) imesa->sarea->last_enqueue + + +typedef void (*i830_tri_func)(i830ContextPtr, i830Vertex *, i830Vertex *, + i830Vertex *); +typedef void (*i830_line_func)(i830ContextPtr, i830Vertex *, i830Vertex *); +typedef void (*i830_point_func)(i830ContextPtr, i830Vertex *); + +#define I830_MAX_TEXTURE_UNITS 4 + +#define I830_FALLBACK_TEXTURE 0x1 +#define I830_FALLBACK_DRAW_BUFFER 0x2 +#define I830_FALLBACK_READ_BUFFER 0x4 +#define I830_FALLBACK_COLORMASK 0x8 +#define I830_FALLBACK_RENDERMODE 0x10 +#define I830_FALLBACK_STENCIL 0x20 +#define I830_FALLBACK_STIPPLE 0x40 +#define I830_FALLBACK_USER 0x80 + +struct i830_context_t +{ + GLint refcount; + GLcontext *glCtx; + + /*From I830 stuff*/ + int TextureMode; + GLuint renderindex; + GLuint TexBlendWordsUsed[I830_MAX_TEXTURE_UNITS]; + GLuint TexBlend[I830_MAX_TEXTURE_UNITS][I830_TEXBLEND_SIZE]; + GLuint Init_TexBlend[I830_MAX_TEXTURE_UNITS][I830_TEXBLEND_SIZE]; + GLuint Init_TexBlendWordsUsed[I830_MAX_TEXTURE_UNITS]; + GLuint Init_BufferSetup[I830_DEST_SETUP_SIZE]; + GLuint LodBias[I830_MAX_TEXTURE_UNITS]; + + GLenum palette_format; + GLuint palette[256]; + + + GLuint Init_Setup[I830_CTX_SETUP_SIZE]; + GLuint vertex_prim; + drmBufPtr vertex_dma_buffer; + + GLboolean mask_red; + GLboolean mask_green; + GLboolean mask_blue; + GLboolean mask_alpha; + + GLubyte clear_red; + GLubyte clear_green; + GLubyte clear_blue; + GLubyte clear_alpha; + + GLfloat depth_scale; + int depth_clear_mask; + int stencil_clear_mask; + int ClearDepth; + int hw_stencil; + + GLuint MonoColor; + + GLuint LastTexEnabled; + GLuint TexEnabledMask; + + /* Texture object bookkeeping + */ + unsigned nr_heaps; + driTexHeap * texture_heaps[1]; + driTextureObject swapped; + + struct i830_texture_object_t *CurrentTexObj[I830_MAX_TEXTURE_UNITS]; + + /* Rasterization and vertex state: + */ + GLuint Fallback; + GLuint NewGLState; + + /* Vertex state + */ + GLuint vertex_size; + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + GLuint vertex_attr_count; + char *verts; /* points to tnl->clipspace.vertex_buf */ + + + /* State for i830tris.c. + */ + GLuint RenderIndex; + GLmatrix ViewportMatrix; + GLenum render_primitive; + GLenum reduced_primitive; + GLuint hw_primitive; + + drmBufPtr vertex_buffer; + char *vertex_addr; + GLuint vertex_low; + GLuint vertex_high; + GLuint vertex_last_prim; + + GLboolean upload_cliprects; + + + /* Fallback rasterization functions + */ + i830_point_func draw_point; + i830_line_func draw_line; + i830_tri_func draw_tri; + + /* Hardware state + */ + GLuint dirty; /* I810_UPLOAD_* */ + GLuint Setup[I830_CTX_SETUP_SIZE]; + GLuint BufferSetup[I830_DEST_SETUP_SIZE]; + GLuint StippleSetup[I830_STP_SETUP_SIZE]; + unsigned int lastStamp; + GLboolean hw_stipple; + + GLenum TexEnvImageFmt[2]; + + /* State which can't be computed completely on the fly: + */ + GLuint LcsCullMode; + GLuint LcsLineWidth; + GLuint LcsPointSize; + + /* Funny mesa mirrors + */ + GLuint ClearColor; + + /* DRI stuff + */ + GLuint needClip; + GLframebuffer *glBuffer; + + /* These refer to the current draw (front vs. back) buffer: + */ + char *drawMap; /* draw buffer address in virtual mem */ + char *readMap; + int drawX; /* origin of drawable in draw buffer */ + int drawY; + GLuint numClipRects; /* cliprects for that buffer */ + drm_clip_rect_t *pClipRects; + + int lastSwap; + int texAge; + int ctxAge; + int dirtyAge; + int perf_boxes; + + int do_irqs; + + GLboolean scissor; + drm_clip_rect_t draw_rect; + drm_clip_rect_t scissor_rect; + + drm_context_t hHWContext; + drmLock *driHwLock; + int driFd; + + __DRIdrawablePrivate *driDrawable; /**< DRI drawable bound to this + * context for drawing. + */ + __DRIdrawablePrivate *driReadable; /**< DRI drawable bound to this + * context for reading. + */ + + /** + * Drawable used by Mesa for software fallbacks for reading and + * writing. It is set by Mesa's \c SetBuffer callback, and will always be + * either \c i830_context_t::driDrawable or \c i830_context_t::driReadable. + */ + + __DRIdrawablePrivate * mesa_drawable; + + __DRIscreenPrivate *driScreen; + i830ScreenPrivate *i830Screen; + I830SAREAPtr sarea; + + /** + * Configuration cache + */ + driOptionCache optionCache; +}; + + +#define I830_TEX_UNIT_ENABLED(unit) (1<<unit) +#define VALID_I830_TEXTURE_OBJECT(tobj) (tobj) + +#define I830_CONTEXT(ctx) ((i830ContextPtr)(ctx->DriverCtx)) +#define I830_DRIVER_DATA(vb) ((i830VertexBufferPtr)((vb)->driver_data)) +#define GET_DISPATCH_AGE(imesa) imesa->sarea->last_dispatch +#define GET_ENQUEUE_AGE(imesa) imesa->sarea->last_enqueue + + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( imesa ) \ +do { \ + char __ret=0; \ + DRM_CAS(imesa->driHwLock, imesa->hHWContext, \ + (DRM_LOCK_HELD|imesa->hHWContext), __ret); \ + if (__ret) \ + i830GetLock( imesa, 0 ); \ +}while (0) + + + /* Unlock the hardware using the global current context + */ +#define UNLOCK_HARDWARE(imesa) \ +do { \ + imesa->perf_boxes |= imesa->sarea->perf_boxes; \ + DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext); \ +} while (0) + + /* This is the wrong way to do it, I'm sure. Otherwise the drm + * bitches that I've already got the heavyweight lock. At worst, + * this is 3 ioctls. The best solution probably only gets me down + * to 2 ioctls in the worst case. + */ +#define LOCK_HARDWARE_QUIESCENT( imesa ) do { \ + LOCK_HARDWARE( imesa ); \ + i830RegetLockQuiescent( imesa ); \ +} while(0) + + + +extern void i830GetLock(i830ContextPtr imesa, GLuint flags); +extern void i830EmitHwStateLocked(i830ContextPtr imesa); +extern void i830EmitDrawingRectangle(i830ContextPtr imesa); +extern void i830XMesaSetBackClipRects(i830ContextPtr imesa); +extern void i830XMesaSetFrontClipRects(i830ContextPtr imesa); +extern void i830DDExtensionsInit(GLcontext *ctx); +extern void i830DDInitDriverFuncs(GLcontext *ctx); +extern void i830DDUpdateHwState(GLcontext *ctx); + +#define SUBPIXEL_X 0.125 +#define SUBPIXEL_Y 0.125 + + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 1 +#if DO_DEBUG +extern int I830_DEBUG; +#else +#define I830_DEBUG 0 +#endif + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_PRIMS 0x8 +#define DEBUG_VERTS 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_DRI 0x80 +#define DEBUG_DMA 0x100 +#define DEBUG_SANITY 0x200 +#define DEBUG_SYNC 0x400 +#define DEBUG_SLEEP 0x800 + + +#define PCI_CHIP_845_G 0x2562 +#define PCI_CHIP_I830_M 0x3577 +#define PCI_CHIP_I855_GM 0x3582 +#define PCI_CHIP_I865_G 0x2572 + + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_debug.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_debug.c new file mode 100644 index 000000000..eee48f1c1 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_debug.c @@ -0,0 +1,415 @@ +/************************************************************************** + +Copyright 2001 2d3d Inc., Delray Beach, FL + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_debug.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + */ + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" + +#include "mm.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_state.h" +#include "i830_tex.h" +#include "i830_tris.h" +#include "i830_ioctl.h" +#include "i830_debug.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + + +#define TINY_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(0) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_XYZ) + +#define NOTEX_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(0) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +#define TEX0_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(1) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +#define TEX1_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \ + VRTX_TEX_COORD_COUNT(2) | \ + VRTX_HAS_DIFFUSE | \ + VRTX_HAS_SPEC | \ + VRTX_HAS_XYZW) + +#define PROJ_VF2 (STATE3D_VERTEX_FORMAT_2_CMD | \ + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) | \ + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) | \ + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) | \ + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D)) + +#define NON_PROJ_VF2 (STATE3D_VERTEX_FORMAT_2_CMD | \ + VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) | \ + VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) | \ + VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) | \ + VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D)) + +void i830DumpContextState( i830ContextPtr imesa ) +{ + GLuint *Context = imesa->Setup; + + fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "STATE1 : 0x%08x\n", Context[I830_CTXREG_STATE1]); + fprintf(stderr, "STATE2 : 0x%08x\n", Context[I830_CTXREG_STATE2]); + fprintf(stderr, "STATE3 : 0x%08x\n", Context[I830_CTXREG_STATE3]); + fprintf(stderr, "STATE4 : 0x%08x\n", Context[I830_CTXREG_STATE4]); + fprintf(stderr, "STATE5 : 0x%08x\n", Context[I830_CTXREG_STATE5]); + fprintf(stderr, "IALPHAB : 0x%08x\n", Context[I830_CTXREG_IALPHAB]); + fprintf(stderr, "STENCILTST : 0x%08x\n", Context[I830_CTXREG_STENCILTST]); + fprintf(stderr, "ENABLES_1 : 0x%08x\n", Context[I830_CTXREG_ENABLES_1]); + fprintf(stderr, "ENABLES_2 : 0x%08x\n", Context[I830_CTXREG_ENABLES_2]); + fprintf(stderr, "AA : 0x%08x\n", Context[I830_CTXREG_AA]); + fprintf(stderr, "FOGCOLOR : 0x%08x\n", Context[I830_CTXREG_FOGCOLOR]); + fprintf(stderr, "BCOLOR0 : 0x%08x\n", Context[I830_CTXREG_BLENDCOLR0]); + fprintf(stderr, "BCOLOR : 0x%08x\n", Context[I830_CTXREG_BLENDCOLR]); + fprintf(stderr, "VF : 0x%08x\n", Context[I830_CTXREG_VF]); + fprintf(stderr, "VF2 : 0x%08x\n", Context[I830_CTXREG_VF2]); + fprintf(stderr, "MCSB0 : 0x%08x\n", Context[I830_CTXREG_MCSB0]); + fprintf(stderr, "MCSB1 : 0x%08x\n", Context[I830_CTXREG_MCSB1]); +} + +void i830DumpBufferState( i830ContextPtr imesa ) +{ + GLuint *Buffer = imesa->BufferSetup; + + fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "CBUFADDR : 0x%08x\n", Buffer[I830_DESTREG_CBUFADDR]); + fprintf(stderr, "DBUFADDR : 0x%08x\n", Buffer[I830_DESTREG_DBUFADDR]); + fprintf(stderr, "DV0 : 0x%08x\n", Buffer[I830_DESTREG_DV0]); + fprintf(stderr, "DV1 : 0x%08x\n", Buffer[I830_DESTREG_DV1]); + fprintf(stderr, "SENABLE : 0x%08x\n", Buffer[I830_DESTREG_SENABLE]); + fprintf(stderr, "SR0 : 0x%08x\n", Buffer[I830_DESTREG_SR0]); + fprintf(stderr, "SR1 : 0x%08x\n", Buffer[I830_DESTREG_SR1]); + fprintf(stderr, "SR2 : 0x%08x\n", Buffer[I830_DESTREG_SR2]); + fprintf(stderr, "DR0 : 0x%08x\n", Buffer[I830_DESTREG_DR0]); + fprintf(stderr, "DR1 : 0x%08x\n", Buffer[I830_DESTREG_DR1]); + fprintf(stderr, "DR2 : 0x%08x\n", Buffer[I830_DESTREG_DR2]); + fprintf(stderr, "DR3 : 0x%08x\n", Buffer[I830_DESTREG_DR3]); + fprintf(stderr, "DR4 : 0x%08x\n", Buffer[I830_DESTREG_DR4]); +} + +void i830DumpStippleState( i830ContextPtr imesa ) +{ + GLuint *Buffer = imesa->BufferSetup; + + fprintf(stderr, "%s\n", __FUNCTION__); + fprintf(stderr, "ST1 : 0x%08x\n", Buffer[I830_STPREG_ST1]); +} + +void i830DumpTextureState( i830ContextPtr imesa, int unit ) +{ + i830TextureObjectPtr t = imesa->CurrentTexObj[unit]; + + if(t) { + fprintf(stderr, "%s : unit %d\n", __FUNCTION__, unit); + fprintf(stderr, "TM0LI : 0x%08x\n", t->Setup[I830_TEXREG_TM0LI]); + fprintf(stderr, "TM0S0 : 0x%08x\n", t->Setup[I830_TEXREG_TM0S0]); + fprintf(stderr, "TM0S1 : 0x%08x\n", t->Setup[I830_TEXREG_TM0S1]); + fprintf(stderr, "TM0S2 : 0x%08x\n", t->Setup[I830_TEXREG_TM0S2]); + fprintf(stderr, "TM0S3 : 0x%08x\n", t->Setup[I830_TEXREG_TM0S3]); + fprintf(stderr, "TM0S4 : 0x%08x\n", t->Setup[I830_TEXREG_TM0S4]); + fprintf(stderr, "NOP0 : 0x%08x\n", t->Setup[I830_TEXREG_NOP0]); + fprintf(stderr, "NOP1 : 0x%08x\n", t->Setup[I830_TEXREG_NOP1]); + fprintf(stderr, "NOP2 : 0x%08x\n", t->Setup[I830_TEXREG_NOP2]); + fprintf(stderr, "MCS : 0x%08x\n", t->Setup[I830_TEXREG_MCS]); + } +} + +void i830DumpTextureBlendState( i830ContextPtr imesa, int unit ) +{ + GLuint *TexBlend = imesa->TexBlend[unit]; + GLuint length = imesa->TexBlendWordsUsed[unit]; + int i; + + fprintf(stderr, "%s : unit %d : length %d\n", __FUNCTION__, unit, length); + for(i = 0; i < length; i++) { + fprintf(stderr, "[%d] : 0x%08x\n", i, TexBlend[i]); + } +} + +void i830VertexSanity( i830ContextPtr imesa, drmI830Vertex vertex ) +{ + I830SAREAPtr sarea = imesa->sarea; + char *prim_name; + int size = 0; + int vfmt_size = 0; + int hw_nr_vertex = 0; + int hw_start_vertex = 0; + + /* Do a bunch of sanity checks on the vertices sent to the hardware */ + + size = vertex.used - 4; + if(imesa->vertex_size && (size % imesa->vertex_size) != 0) { + fprintf(stderr, "\n\nVertex size does not match imesa " + "internal state\n"); + fprintf(stderr, "Buffer size : %d\n", size); + fprintf(stderr, "Vertex size : %d\n", imesa->vertex_size); + } + + /* Check to see if the vertex format is good, and get its size */ + if (sarea->ContextState[I830_CTXREG_VF] == TINY_VERTEX_FORMAT) { + vfmt_size = 16; /* 4 dwords */ + } else if (sarea->ContextState[I830_CTXREG_VF] == + NOTEX_VERTEX_FORMAT) { + vfmt_size = 24; /* 6 dwords */ + } else if (sarea->ContextState[I830_CTXREG_VF] == + TEX0_VERTEX_FORMAT) { + vfmt_size = 32; /* 8 dwords */ + if (sarea->ContextState[I830_CTXREG_VF2] != NON_PROJ_VF2) { + fprintf(stderr, "\n\nTex 0 vertex format, but proj " + "texturing\n"); + } + } else if(sarea->ContextState[I830_CTXREG_VF] == + TEX1_VERTEX_FORMAT) { + if (sarea->ContextState[I830_CTXREG_VF2] == NON_PROJ_VF2) + vfmt_size = 40; /* 10 dwords */ + else + vfmt_size = 48; /* 12 dwords */ + } else { + fprintf(stderr, "\n\nUnknown vertex format : vf : %08x " + "vf2 : %08x\n", + sarea->ContextState[I830_CTXREG_VF], + sarea->ContextState[I830_CTXREG_VF2]); + } + + if(vfmt_size && (size % vfmt_size) != 0) { + fprintf(stderr, "\n\nVertex size does not match hardware " + "internal state\n"); + fprintf(stderr, "Buffer size : %d\n", size); + fprintf(stderr, "Vertex size : %d\n", vfmt_size); + } + + switch(sarea->vertex_prim) { + case PRIM3D_POINTLIST: + hw_start_vertex = 0; + hw_nr_vertex = 1; + prim_name = "PointList"; + break; + + case PRIM3D_LINELIST: + hw_start_vertex = 0; + hw_nr_vertex = 2; + prim_name = "LineList"; + break; + + case PRIM3D_LINESTRIP: + hw_start_vertex = 2; + hw_nr_vertex = 1; + prim_name = "LineStrip"; + break; + + case PRIM3D_TRILIST: + hw_start_vertex = 0; + hw_nr_vertex = 3; + prim_name = "TriList"; + break; + + case PRIM3D_TRISTRIP: + hw_start_vertex = 3; + hw_nr_vertex = 1; + prim_name = "TriStrip"; + break; + + case PRIM3D_TRIFAN: + hw_start_vertex = 3; + hw_nr_vertex = 1; + prim_name = "TriFan"; + break; + + case PRIM3D_POLY: + hw_start_vertex = 3; + hw_nr_vertex = 1; + prim_name = "Polygons"; + break; + default: + prim_name = "Unknown"; + fprintf(stderr, "\n\nUnknown primitive type : %08x\n", + sarea->vertex_prim); + } + + if (hw_nr_vertex && vfmt_size) { + int temp_size = size - (hw_start_vertex * vfmt_size); + int remaining = (temp_size % (hw_nr_vertex * vfmt_size)); + + if (remaining != 0) { + fprintf(stderr, "\n\nThis buffer contains an improper" + " multiple of vertices for this primitive : %s\n", + prim_name); + fprintf(stderr, "Number of vertices in buffer : %d\n", + size / vfmt_size); + fprintf(stderr, "temp_size : %d\n", temp_size); + fprintf(stderr, "remaining vertices : %d", + remaining / vfmt_size); + } + } + if (vfmt_size) { + fprintf(stderr, "\n\nPrim name (%s), vertices (%d)\n", + prim_name, + size / vfmt_size); + } +} + +void i830EmitHwStateLockedDebug( i830ContextPtr imesa ) +{ + int i; + + if ((imesa->dirty & I830_UPLOAD_TEX0_IMAGE) && imesa->CurrentTexObj[0]) { + i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[0]); + } + + if ((imesa->dirty & I830_UPLOAD_TEX1_IMAGE) && imesa->CurrentTexObj[1]) { + i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[1]); + } + + if (imesa->dirty & I830_UPLOAD_CTX) { + memcpy( imesa->sarea->ContextState, + imesa->Setup, sizeof(imesa->Setup) ); + i830DumpContextState(imesa); + } + + for(i = 0; i < I830_TEXTURE_COUNT; i++) { + if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) { + unsigned * TexState; + + imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i); + + switch( i ) { + case 0: + case 1: + TexState = imesa->sarea->TexState[i]; + break; + + case 2: + TexState = imesa->sarea->TexState2; + break; + + case 3: + TexState = imesa->sarea->TexState3; + break; + } + + memcpy(TexState, imesa->CurrentTexObj[i]->Setup, + sizeof(imesa->sarea->TexState[i])); + i830DumpTextureState(imesa, i); + } + } + /* Need to figure out if texturing state, or enable changed. */ + + for(i = 0; i < I830_TEXBLEND_COUNT; i++) { + if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) { + unsigned * TexBlendState; + unsigned * words_used; + + imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i); + + switch( i ) { + case 0: + case 1: + TexBlendState = imesa->sarea->TexBlendState[i]; + words_used = & imesa->sarea->TexBlendStateWordsUsed[i]; + break; + + case 2: + TexBlendState = imesa->sarea->TexBlendState2; + words_used = & imesa->sarea->TexBlendStateWordsUsed2; + break; + + case 3: + TexBlendState = imesa->sarea->TexBlendState3; + words_used = & imesa->sarea->TexBlendStateWordsUsed3; + break; + } + + memcpy(TexBlendState, imesa->TexBlend[i], + imesa->TexBlendWordsUsed[i] * 4); + *words_used = imesa->TexBlendWordsUsed[i]; + + i830DumpTextureBlendState(imesa, i); + } + } + + if (imesa->dirty & I830_UPLOAD_BUFFERS) { + memcpy( imesa->sarea->BufferState,imesa->BufferSetup, + sizeof(imesa->BufferSetup) ); + i830DumpBufferState(imesa); + } + + if (imesa->dirty & I830_UPLOAD_STIPPLE) { + fprintf(stderr, "UPLOAD_STIPPLE\n"); + memcpy( imesa->sarea->StippleState,imesa->StippleSetup, + sizeof(imesa->StippleSetup) ); + i830DumpStippleState(imesa); + } + + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { + memcpy( imesa->sarea->Palette[0],imesa->palette, + sizeof(imesa->sarea->Palette[0])); + } else { + i830TextureObjectPtr p; + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { + p = imesa->CurrentTexObj[0]; + memcpy( imesa->sarea->Palette[0],p->palette, + sizeof(imesa->sarea->Palette[0])); + } + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { + p = imesa->CurrentTexObj[1]; + memcpy( imesa->sarea->Palette[1], + p->palette, + sizeof(imesa->sarea->Palette[1])); + } + } + imesa->sarea->dirty |= (imesa->dirty & ~(I830_UPLOAD_TEX_MASK | + I830_UPLOAD_TEXBLEND_MASK)); + + imesa->upload_cliprects = GL_TRUE; + imesa->dirty = 0; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_debug.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_debug.h new file mode 100644 index 000000000..deb84f7b0 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_debug.h @@ -0,0 +1,48 @@ +/************************************************************************** + +Copyright 2001 2d3d Inc., Delray Beach, FL + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_debug.h,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + */ + +/* Defines for sanity checking and debug output */ +#ifndef I830DEBUG_INC +#define I830DEBUG_INC + + +void i830DumpContextState( i830ContextPtr imesa ); +void i830DumpStippleState( i830ContextPtr imesa ); +void i830DumpBufferState( i830ContextPtr imesa ); +void i830DumpTextureState( i830ContextPtr imesa, int unit ); +void i830DumpTextureBlendState( i830ContextPtr imesa, int unit ); +void i830VertexSanity( i830ContextPtr imesa, drmI830Vertex vertex ); +void i830EmitHwStateLockedDebug( i830ContextPtr imesa ); + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_ioctl.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_ioctl.c new file mode 100644 index 000000000..cd0c143df --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_ioctl.c @@ -0,0 +1,841 @@ + +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c,v 1.5 2002/12/10 01:26:53 dawes Exp $ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * Graeme Fisher <graeme@2d3d.co.za> + * Abraham vd Merwe <abraham@2d3d.co.za> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include <stdio.h> +#include <unistd.h> +#include <errno.h> + +#include "glheader.h" +#include "mtypes.h" +#include "macros.h" +#include "dd.h" +#include "swrast/swrast.h" + +#include "mm.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_ioctl.h" +#include "i830_state.h" +#include "i830_debug.h" + +#include "drm.h" + +static drmBufPtr i830_get_buffer_ioctl( i830ContextPtr imesa ) +{ + drmI830DMA dma; + drmBufPtr buf; + int retcode,i = 0; + while (1) { + retcode = drmCommandWriteRead(imesa->driFd, + DRM_I830_GETBUF, + &dma, + sizeof(drmI830DMA)); + if (dma.granted == 1 && retcode == 0) + break; + + if (++i > 1000) { + imesa->sarea->perf_boxes |= I830_BOX_WAIT; + retcode = drmCommandNone(imesa->driFd, DRM_I830_FLUSH); + i = 0; + } + } + + buf = &(imesa->i830Screen->bufs->list[dma.request_idx]); + buf->idx = dma.request_idx; + buf->used = 0; + buf->total = dma.request_size; + buf->address = (drmAddress)dma.virtual; + + return buf; +} + +static void i830ClearDrawQuad(i830ContextPtr imesa, float left, + float right, + float bottom, float top, GLubyte red, + GLubyte green, GLubyte blue, GLubyte alpha) +{ + GLuint *vb = i830AllocDmaLowLocked( imesa, 128 ); + i830Vertex tmp; + int i; + + /* PRIM3D_TRIFAN */ + + /* initial vertex, left bottom */ + tmp.v.x = left; + tmp.v.y = bottom; + tmp.v.z = 1.0; + tmp.v.w = 1.0; + tmp.v.color.red = red; + tmp.v.color.green = green; + tmp.v.color.blue = blue; + tmp.v.color.alpha = alpha; + tmp.v.specular.red = 0; + tmp.v.specular.green = 0; + tmp.v.specular.blue = 0; + tmp.v.specular.alpha = 0; + tmp.v.u0 = 0.0f; + tmp.v.v0 = 0.0f; + for (i = 0 ; i < 8 ; i++) + vb[i] = tmp.ui[i]; + + /* right bottom */ + vb += 8; + tmp.v.x = right; + for (i = 0 ; i < 8 ; i++) + vb[i] = tmp.ui[i]; + + /* right top */ + vb += 8; + tmp.v.y = top; + for (i = 0 ; i < 8 ; i++) + vb[i] = tmp.ui[i]; + + /* left top */ + vb += 8; + tmp.v.x = left; + for (i = 0 ; i < 8 ; i++) + vb[i] = tmp.ui[i]; +} + +static void i830ClearWithTris(GLcontext *ctx, GLbitfield mask, + GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + i830ScreenPrivate *i830Screen = imesa->i830Screen; + I830SAREAPtr sarea = imesa->sarea; + GLuint old_vertex_prim; + GLuint old_dirty; + int x0, y0, x1, y1; + + if (I830_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "Clearing with triangles\n"); + + old_dirty = imesa->dirty & ~I830_UPLOAD_CLIPRECTS; + /* Discard all the dirty flags except the cliprect one, reset later */ + imesa->dirty &= I830_UPLOAD_CLIPRECTS; + + if(!all) { + x0 = cx; + y0 = cy; + x1 = x0 + cw; + y1 = y0 + ch; + } else { + x0 = 0; + y0 = 0; + x1 = x0 + dPriv->w; + y1 = y0 + dPriv->h; + } + + /* Clip to Screen */ + if (x0 < 0) x0 = 0; + if (y0 < 0) y0 = 0; + if (x1 > i830Screen->width-1) x1 = i830Screen->width-1; + if (y1 > i830Screen->height-1) y1 = i830Screen->height-1; + + LOCK_HARDWARE(imesa); + memcpy(sarea->ContextState, + imesa->Init_Setup, + sizeof(imesa->Setup) ); + memcpy(sarea->BufferState, + imesa->BufferSetup, + sizeof(imesa->BufferSetup) ); + sarea->StippleState[I830_STPREG_ST1] = 0; + + old_vertex_prim = imesa->hw_primitive; + imesa->hw_primitive = PRIM3D_TRIFAN; + + if(mask & BUFFER_BIT_FRONT_LEFT) { + GLuint tmp = sarea->ContextState[I830_CTXREG_ENABLES_2]; + + sarea->dirty |= (I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS | + I830_UPLOAD_TEXBLEND0); + + sarea->TexBlendState[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXOP_LAST_STAGE | + TEXBLENDOP_ARG1); + sarea->TexBlendState[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + sarea->TexBlendState[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + sarea->TexBlendState[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + sarea->TexBlendStateWordsUsed[0] = 4; + + tmp &= ~(ENABLE_STENCIL_WRITE | ENABLE_DEPTH_WRITE); + tmp |= (DISABLE_STENCIL_WRITE | + DISABLE_DEPTH_WRITE | + (imesa->mask_red << WRITEMASK_RED_SHIFT) | + (imesa->mask_green << WRITEMASK_GREEN_SHIFT) | + (imesa->mask_blue << WRITEMASK_BLUE_SHIFT) | + (imesa->mask_alpha << WRITEMASK_ALPHA_SHIFT)); + sarea->ContextState[I830_CTXREG_ENABLES_2] = tmp; + + if(0) + fprintf(stderr, "fcdq : r_mask(%d) g_mask(%d) b_mask(%d) a_mask(%d)\n", + imesa->mask_red, imesa->mask_green, imesa->mask_blue, + imesa->mask_alpha); + + sarea->BufferState[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset; + + if(0) + fprintf(stderr, "fcdq : x0(%d) x1(%d) y0(%d) y1(%d)\n" + "r(0x%x) g(0x%x) b(0x%x) a(0x%x)\n", + x0, x1, y0, y1, imesa->clear_red, imesa->clear_green, + imesa->clear_blue, imesa->clear_alpha); + + i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1, + imesa->clear_red, imesa->clear_green, + imesa->clear_blue, imesa->clear_alpha); + i830FlushPrimsLocked( imesa ); + } + + if(mask & BUFFER_BIT_BACK_LEFT) { + GLuint tmp = sarea->ContextState[I830_CTXREG_ENABLES_2]; + + sarea->dirty |= (I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS | + I830_UPLOAD_TEXBLEND0); + + sarea->TexBlendState[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXOP_LAST_STAGE | + TEXBLENDOP_ARG1); + sarea->TexBlendState[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + sarea->TexBlendState[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + sarea->TexBlendState[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + sarea->TexBlendStateWordsUsed[0] = 4; + + tmp &= ~(ENABLE_STENCIL_WRITE | ENABLE_DEPTH_WRITE); + tmp |= (DISABLE_STENCIL_WRITE | + DISABLE_DEPTH_WRITE | + (imesa->mask_red << WRITEMASK_RED_SHIFT) | + (imesa->mask_green << WRITEMASK_GREEN_SHIFT) | + (imesa->mask_blue << WRITEMASK_BLUE_SHIFT) | + (imesa->mask_alpha << WRITEMASK_ALPHA_SHIFT)); + + if(0) + fprintf(stderr, "bcdq : r_mask(%d) g_mask(%d) b_mask(%d) a_mask(%d)\n", + imesa->mask_red, imesa->mask_green, imesa->mask_blue, + imesa->mask_alpha); + + sarea->ContextState[I830_CTXREG_ENABLES_2] = tmp; + + sarea->BufferState[I830_DESTREG_CBUFADDR] = i830Screen->backOffset; + + if(0) + fprintf(stderr, "bcdq : x0(%d) x1(%d) y0(%d) y1(%d)\n" + "r(0x%x) g(0x%x) b(0x%x) a(0x%x)\n", + x0, x1, y0, y1, imesa->clear_red, imesa->clear_green, + imesa->clear_blue, imesa->clear_alpha); + + i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1, + imesa->clear_red, imesa->clear_green, + imesa->clear_blue, imesa->clear_alpha); + i830FlushPrimsLocked( imesa ); + } + + if(mask & BUFFER_BIT_STENCIL) { + GLuint s_mask = ctx->Stencil.WriteMask[0]; + + sarea->dirty |= (I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS | + I830_UPLOAD_TEXBLEND0); + + sarea->TexBlendState[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXOP_LAST_STAGE | + TEXBLENDOP_ARG1); + sarea->TexBlendState[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + sarea->TexBlendState[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + sarea->TexBlendState[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_ALPHA | + TEXBLEND_ARG2 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + sarea->TexBlendStateWordsUsed[0] = 4; + + sarea->ContextState[I830_CTXREG_ENABLES_1] |= (ENABLE_STENCIL_TEST | + ENABLE_DEPTH_TEST); + + sarea->ContextState[I830_CTXREG_ENABLES_2] &= ~(ENABLE_STENCIL_WRITE | + ENABLE_DEPTH_WRITE | + ENABLE_COLOR_WRITE); + + sarea->ContextState[I830_CTXREG_ENABLES_2] |= + (ENABLE_STENCIL_WRITE | + DISABLE_DEPTH_WRITE | + (1 << WRITEMASK_RED_SHIFT) | + (1 << WRITEMASK_GREEN_SHIFT) | + (1 << WRITEMASK_BLUE_SHIFT) | + (1 << WRITEMASK_ALPHA_SHIFT) | + ENABLE_COLOR_WRITE); + + sarea->ContextState[I830_CTXREG_STATE4] &= + ~MODE4_ENABLE_STENCIL_WRITE_MASK; + + sarea->ContextState[I830_CTXREG_STATE4] |= + (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(s_mask)); + + sarea->ContextState[I830_CTXREG_STENCILTST] &= + ~(STENCIL_OPS_MASK | + STENCIL_REF_VALUE_MASK | + ENABLE_STENCIL_TEST_FUNC_MASK); + + sarea->ContextState[I830_CTXREG_STENCILTST] |= + (ENABLE_STENCIL_PARMS | + ENABLE_STENCIL_REF_VALUE | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_FAIL_OP(STENCILOP_REPLACE) | + STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_REPLACE) | + STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_REPLACE) | + STENCIL_REF_VALUE((ctx->Stencil.Clear & 0xff)) | + STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS)); + + if(0) + fprintf(stderr, "Enables_1 (0x%x) Enables_2 (0x%x) StenTst (0x%x)\n" + "Modes_4 (0x%x)\n", + sarea->ContextState[I830_CTXREG_ENABLES_1], + sarea->ContextState[I830_CTXREG_ENABLES_2], + sarea->ContextState[I830_CTXREG_STENCILTST], + sarea->ContextState[I830_CTXREG_STATE4]); + + sarea->BufferState[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset; + + i830ClearDrawQuad(imesa, (float)x0, (float)x1, (float)y0, (float)y1, + 255, 255, 255, 255); + i830FlushPrimsLocked( imesa ); + } + + UNLOCK_HARDWARE(imesa); + imesa->dirty = old_dirty; + imesa->dirty |= (I830_UPLOAD_CTX | + I830_UPLOAD_BUFFERS | + I830_UPLOAD_TEXBLEND0); + + imesa->hw_primitive = old_vertex_prim; +} + +static void i830Clear(GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx1, GLint cy1, GLint cw, GLint ch) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + drmI830Clear clear; + GLbitfield tri_mask = 0; + int i; + GLint cx, cy; + + /* flip top to bottom */ + cy = dPriv->h-cy1-ch; + cx = cx1 + imesa->drawX; + cy += imesa->drawY; + + if(0) fprintf(stderr, "\nClearColor : 0x%08x\n", imesa->ClearColor); + + clear.flags = 0; + clear.clear_color = imesa->ClearColor; + clear.clear_depth = 0; + clear.clear_colormask = 0; + clear.clear_depthmask = 0; + + I830_FIREVERTICES( imesa ); + + if (mask & BUFFER_BIT_FRONT_LEFT) { + if(colorMask == ~0) { + clear.flags |= I830_FRONT; + } else { + tri_mask |= BUFFER_BIT_FRONT_LEFT; + } + mask &= ~BUFFER_BIT_FRONT_LEFT; + } + + if (mask & BUFFER_BIT_BACK_LEFT) { + if(colorMask == ~0) { + clear.flags |= I830_BACK; + } else { + tri_mask |= BUFFER_BIT_BACK_LEFT; + } + mask &= ~BUFFER_BIT_BACK_LEFT; + } + + if (mask & BUFFER_BIT_DEPTH) { + clear.flags |= I830_DEPTH; + clear.clear_depthmask = imesa->depth_clear_mask; + clear.clear_depth = (GLuint)(ctx->Depth.Clear * imesa->ClearDepth); + mask &= ~BUFFER_BIT_DEPTH; + } + + if((mask & BUFFER_BIT_STENCIL) && imesa->hw_stencil) { + if (ctx->Stencil.WriteMask[0] != 0xff) { + tri_mask |= BUFFER_BIT_STENCIL; + } else { + clear.flags |= I830_DEPTH; + clear.clear_depthmask |= imesa->stencil_clear_mask; + clear.clear_depth |= (ctx->Stencil.Clear & 0xff) << 24; + } + mask &= ~BUFFER_BIT_STENCIL; + } + + /* First check for clears that need to happen with triangles */ + if(tri_mask) { + i830ClearWithTris(ctx, tri_mask, all, cx, cy, cw, ch); + } + + if (clear.flags) { + LOCK_HARDWARE( imesa ); + + for (i = 0 ; i < imesa->numClipRects ; ) + { + int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, imesa->numClipRects); + drm_clip_rect_t *box = imesa->pClipRects; + drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes; + int n = 0; + + if (!all) { + for ( ; i < nr ; i++) { + GLint x = box[i].x1; + GLint y = box[i].y1; + GLint w = box[i].x2 - x; + GLint h = box[i].y2 - y; + + if (x < cx) w -= cx - x, x = cx; + if (y < cy) h -= cy - y, y = cy; + if (x + w > cx + cw) w = cx + cw - x; + if (y + h > cy + ch) h = cy + ch - y; + if (w <= 0) continue; + if (h <= 0) continue; + + b->x1 = x; + b->y1 = y; + b->x2 = x + w; + b->y2 = y + h; + b++; + n++; + } + } else { + for ( ; i < nr ; i++) { + *b++ = *(drm_clip_rect_t *)&box[i]; + n++; + } + } + + imesa->sarea->nbox = n; + drmCommandWrite(imesa->driFd, DRM_I830_CLEAR, + &clear, sizeof(drmI830Clear)); + } + + UNLOCK_HARDWARE( imesa ); + imesa->upload_cliprects = GL_TRUE; + } + + if (mask) + _swrast_Clear( ctx, mask, all, cx1, cy1, cw, ch ); +} + + + +/* + * Copy the back buffer to the front buffer. + */ +void i830CopyBuffer( const __DRIdrawablePrivate *dPriv ) +{ + i830ContextPtr imesa; + drm_clip_rect_t *pbox; + int nbox, i, tmp; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate; + + I830_FIREVERTICES( imesa ); + LOCK_HARDWARE( imesa ); + + imesa->sarea->perf_boxes |= imesa->perf_boxes; + imesa->perf_boxes = 0; + + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + + for (i = 0 ; i < nbox ; ) + { + int nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, dPriv->numClipRects); + drm_clip_rect_t *b = (drm_clip_rect_t *)imesa->sarea->boxes; + + imesa->sarea->nbox = nr - i; + + for ( ; i < nr ; i++) + *b++ = pbox[i]; + drmCommandNone(imesa->driFd, DRM_I830_SWAP); + } + + tmp = GET_ENQUEUE_AGE(imesa); + UNLOCK_HARDWARE( imesa ); + + /* multiarb will suck the life out of the server without this throttle: + */ + if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) { + i830WaitAge(imesa, imesa->lastSwap); + } + + imesa->lastSwap = tmp; + imesa->upload_cliprects = GL_TRUE; +} + +/* Flip the front & back buffes + */ +void i830PageFlip( const __DRIdrawablePrivate *dPriv ) +{ +#if 0 + i830ContextPtr imesa; + int tmp, ret; + + if (I830_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s\n", __FUNCTION__); + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + imesa = (i830ContextPtr) dPriv->driContextPriv->driverPrivate; + + I830_FIREVERTICES( imesa ); + LOCK_HARDWARE( imesa ); + + imesa->sarea->perf_boxes |= imesa->perf_boxes; + imesa->perf_boxes = 0; + + if (dPriv->pClipRects) { + *(drm_clip_rect_t *)imesa->sarea->boxes = dPriv->pClipRects[0]; + imesa->sarea->nbox = 1; + } + + ret = drmCommandNone(imesa->driFd, DRM_I830_FLIP); + if (ret) { + fprintf(stderr, "%s: %d\n", __FUNCTION__, ret); + UNLOCK_HARDWARE( imesa ); + exit(1); + } + + tmp = GET_ENQUEUE_AGE(imesa); + UNLOCK_HARDWARE( imesa ); + + /* multiarb will suck the life out of the server without this throttle: + */ + if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) { + i830WaitAge(imesa, imesa->lastSwap); + } + + i830SetDrawBuffer( imesa->glCtx, imesa->glCtx->Color.DriverDrawBuffer ); + imesa->upload_cliprects = GL_TRUE; + imesa->lastSwap = tmp; +#endif +} + +/* This waits for *everybody* to finish rendering -- overkill. + */ +void i830DmaFinish( i830ContextPtr imesa ) +{ + I830_FIREVERTICES( imesa ); + LOCK_HARDWARE_QUIESCENT( imesa ); + UNLOCK_HARDWARE( imesa ); +} + +void i830RegetLockQuiescent( i830ContextPtr imesa ) +{ + drmUnlock(imesa->driFd, imesa->hHWContext); + i830GetLock( imesa, DRM_LOCK_QUIESCENT ); +} + +void i830WaitAgeLocked( i830ContextPtr imesa, int age ) +{ + int i = 0; + while (++i < 5000) { + drmCommandNone(imesa->driFd, DRM_I830_GETAGE); + if (GET_DISPATCH_AGE(imesa) >= age) return; + imesa->sarea->perf_boxes |= I830_BOX_WAIT; + UNLOCK_HARDWARE( imesa ); + if (I830_DEBUG & DEBUG_SLEEP) fprintf(stderr, "."); + usleep(1); + LOCK_HARDWARE( imesa ); + } + /* If that didn't work, just do a flush: + */ + drmCommandNone(imesa->driFd, DRM_I830_FLUSH); +} + +void i830WaitAge( i830ContextPtr imesa, int age ) +{ + int i = 0; + if (GET_DISPATCH_AGE(imesa) >= age) return; + + while (1) { + drmCommandNone(imesa->driFd, DRM_I830_GETAGE); + if (GET_DISPATCH_AGE(imesa) >= age) return; + imesa->perf_boxes |= I830_BOX_WAIT; + + if (imesa->do_irqs) { + drmI830IrqEmit ie; + drmI830IrqWait iw; + int ret; + + ie.irq_seq = &iw.irq_seq; + + LOCK_HARDWARE( imesa ); + ret = drmCommandWriteRead( imesa->driFd, DRM_I830_IRQ_EMIT, &ie, sizeof(ie) ); + if ( ret ) { + fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret ); + exit(1); + } + UNLOCK_HARDWARE(imesa); + + ret = drmCommandWrite( imesa->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) ); + if ( ret ) { + fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret ); + exit(1); + } + } else { + if (++i > 5000) usleep(1); + } + } +} + +static void age_imesa( i830ContextPtr imesa, int age ) +{ + if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->base.timestamp = age; + if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->base.timestamp = age; +} + +void i830FlushPrimsLocked( i830ContextPtr imesa ) +{ + drm_clip_rect_t *pbox = imesa->pClipRects; + int nbox = imesa->numClipRects; + drmBufPtr buffer = imesa->vertex_buffer; + I830SAREAPtr sarea = imesa->sarea; + drmI830Vertex vertex; + int i, nr; + + if (I830_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s dirty: %08x\n", __FUNCTION__, imesa->dirty); + + + vertex.idx = buffer->idx; + vertex.used = imesa->vertex_low; + vertex.discard = 0; + sarea->vertex_prim = imesa->hw_primitive; + + /* Reset imesa vars: + */ + imesa->vertex_buffer = 0; + imesa->vertex_addr = 0; + imesa->vertex_low = 0; + imesa->vertex_high = 0; + imesa->vertex_last_prim = 0; + + if (imesa->dirty) { + if (I830_DEBUG & DEBUG_SANITY) + i830EmitHwStateLockedDebug(imesa); + else + i830EmitHwStateLocked(imesa); + } + + if (I830_DEBUG & DEBUG_IOCTL) + fprintf(stderr,"%s: Vertex idx %d used %d discard %d\n", + __FUNCTION__, vertex.idx, vertex.used, vertex.discard); + + if (!nbox) { + vertex.used = 0; + vertex.discard = 1; + if (drmCommandWrite (imesa->driFd, DRM_I830_VERTEX, + &vertex, sizeof(drmI830Vertex))) { + fprintf(stderr, "DRM_I830_VERTEX: %d\n", -errno); + UNLOCK_HARDWARE(imesa); + exit(1); + } + return; + } + + for (i = 0 ; i < nbox ; i = nr ) { + drm_clip_rect_t *b = sarea->boxes; + int j; + + nr = MIN2(i + I830_NR_SAREA_CLIPRECTS, nbox); + sarea->nbox = nr - i; + + for ( j = i ; j < nr ; j++) { + b[j-i] = pbox[j]; + } + + /* Finished with the buffer? + */ + if (nr == nbox) + vertex.discard = 1; + + /* Do a bunch of sanity checks on the vertices sent to the hardware */ + if (I830_DEBUG & DEBUG_SANITY) { + i830VertexSanity(imesa, vertex); + + for ( j = 0 ; j < sarea->nbox ; j++) { + fprintf(stderr, "box %d/%d %d,%d %d,%d\n", + j, sarea->nbox, b[j].x1, b[j].y1, b[j].x2, b[j].y2); + } + } + + drmCommandWrite (imesa->driFd, DRM_I830_VERTEX, + &vertex, sizeof(drmI830Vertex)); + age_imesa(imesa, imesa->sarea->last_enqueue); + } + + imesa->dirty = 0; + imesa->upload_cliprects = GL_FALSE; +} + +void i830FlushPrimsGetBufferLocked( i830ContextPtr imesa ) +{ + if (imesa->vertex_buffer) + i830FlushPrimsLocked( imesa ); + imesa->vertex_buffer = i830_get_buffer_ioctl( imesa ); + imesa->vertex_addr = (char *)imesa->vertex_buffer->address; + + /* leave room for instruction header & footer: + */ + imesa->vertex_high = imesa->vertex_buffer->total - 4; + imesa->vertex_low = 4; + imesa->vertex_last_prim = imesa->vertex_low; +} + +void i830FlushPrimsGetBuffer( i830ContextPtr imesa ) +{ + LOCK_HARDWARE(imesa); + i830FlushPrimsGetBufferLocked( imesa ); + UNLOCK_HARDWARE(imesa); +} + + +void i830FlushPrims( i830ContextPtr imesa ) +{ + if (imesa->vertex_buffer) { + LOCK_HARDWARE( imesa ); + i830FlushPrimsLocked( imesa ); + UNLOCK_HARDWARE( imesa ); + } +} + +int i830_check_copy(int fd) +{ + return drmCommandNone(fd, DRM_I830_DOCOPY); +} + +static void i830Flush( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + I830_FIREVERTICES( imesa ); +} + +static void i830Finish( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + i830DmaFinish( imesa ); +} + +void i830InitIoctlFuncs( struct dd_function_table *functions ) +{ + functions->Flush = i830Flush; + functions->Clear = i830Clear; + functions->Finish = i830Finish; +} + diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_ioctl.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_ioctl.h new file mode 100644 index 000000000..f92ff44ea --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_ioctl.h @@ -0,0 +1,105 @@ + +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h,v 1.3 2002/10/30 12:51:35 alanh Exp $ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * Graeme Fisher <graeme@2d3d.co.za> + * Abraham vd Merwe <abraham@2d3d.co.za> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef I830_IOCTL_H +#define I830_IOCTL_H + +#include "i830_context.h" + +GLuint *i830AllocDwords (i830ContextPtr imesa, int dwords); +void i830EmitPrim( i830ContextPtr imesa ); +void i830FlushPrims( i830ContextPtr mmesa ); +void i830FlushPrimsLocked( i830ContextPtr mmesa ); +void i830FlushPrimsGetBuffer( i830ContextPtr imesa ); +void i830FlushPrimsGetBufferLocked( i830ContextPtr imesa ); +void i830WaitAgeLocked( i830ContextPtr imesa, int age ); +void i830WaitAge( i830ContextPtr imesa, int age ); +void i830DmaFinish( i830ContextPtr imesa ); +void i830RegetLockQuiescent( i830ContextPtr imesa ); +void i830InitIoctlFuncs( struct dd_function_table *functions ); +void i830CopyBuffer( const __DRIdrawablePrivate *dpriv ); +void i830PageFlip( const __DRIdrawablePrivate *dpriv ); +int i830_check_copy(int fd); + +#define I830_STATECHANGE(imesa, flag) \ +do { \ + if (imesa->vertex_low != imesa->vertex_last_prim) \ + i830FlushPrims(imesa); \ + imesa->dirty |= flag; \ +} while (0) + + +#define I830_FIREVERTICES(imesa) \ +do { \ + if (imesa->vertex_buffer) { \ + i830FlushPrims(imesa); \ +} \ +} while (0) + + +static __inline GLuint *i830AllocDmaLow( i830ContextPtr imesa, int bytes ) +{ + if (imesa->vertex_low + bytes > imesa->vertex_high) { + i830FlushPrimsGetBuffer( imesa ); + } + + { + GLuint *start = (GLuint *)(imesa->vertex_addr + imesa->vertex_low); + imesa->vertex_low += bytes; + return start; + } +} + +static __inline GLuint *i830AllocDmaLowLocked( i830ContextPtr imesa, + int bytes ) +{ + if (imesa->vertex_low + bytes > imesa->vertex_high) { + i830FlushPrimsGetBufferLocked( imesa ); + } + + { + GLuint *start = (GLuint *)(imesa->vertex_addr + imesa->vertex_low); + imesa->vertex_low += bytes; + return start; + } +} + + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_render.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_render.c new file mode 100644 index 000000000..b0592e9cd --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_render.c @@ -0,0 +1,226 @@ +/* + * Intel i810 DRI driver for Mesa 3.5 + * + * Copyright (C) 1999-2000 Keith Whitwell All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL KEITH WHITWELL BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Author: + * Keith Whitwell <keith@tungstengraphics.com> + * Adapted for use on the I830: + * Jeff Hartmann <jhartmann@2d3d.com> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_render.c,v 1.2 2002/12/10 01:26:53 dawes Exp $ */ + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware acceleration where possible. + * + */ +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" +#include "enums.h" + +#include "tnl/t_context.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_tris.h" +#include "i830_state.h" +#include "i830_ioctl.h" + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. + * Try to simulate missing primitives with indexed vertices. + */ +#define HAVE_POINTS 0 /* Has it, but can't use because subpixel has to + * be adjusted for points on the I830/I845G + */ +#define HAVE_LINES 1 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */ +#define HAVE_TRI_FANS 1 +#define HAVE_POLYGONS 1 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 + +#define HAVE_ELTS 0 + +static GLuint hw_prim[GL_POLYGON+1] = { + 0, + PRIM3D_LINELIST, + PRIM3D_LINESTRIP, + PRIM3D_LINESTRIP, + PRIM3D_TRILIST, + PRIM3D_TRISTRIP, + PRIM3D_TRIFAN, + 0, + 0, + PRIM3D_POLY +}; + +static const GLenum reduced_prim[GL_POLYGON+1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + +static const int scale_prim[GL_POLYGON+1] = { + 0, /* fallback case */ + 1, + 2, + 2, + 1, + 3, + 3, + 0, /* fallback case */ + 0, /* fallback case */ + 3 +}; + + +#define LOCAL_VARS i830ContextPtr imesa = I830_CONTEXT(ctx) +#define INIT( prim ) do { \ + I830_STATECHANGE(imesa, 0); \ + i830RasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] ); \ +} while (0) + +#define FLUSH() I830_FIREVERTICES( imesa ) +#define GET_CURRENT_VB_MAX_VERTS() \ + (((int)imesa->vertex_high - (int)imesa->vertex_low) / (imesa->vertex_size*4)) +#define GET_SUBSEQUENT_VB_MAX_VERTS() \ + (I830_DMA_BUF_SZ-8) / (imesa->vertex_size * 4) + + +#define ALLOC_VERTS( nr ) \ + i830AllocDmaLow( imesa, (nr) * imesa->vertex_size * 4) +#define EMIT_VERTS( ctx, j, nr, buf ) \ + _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf) + +#define TAG(x) i830_##x +#include "tnl_dd/t_dd_dmatmp.h" + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + +/* Heuristic for i830, which can only emit a single primitive per dma + * buffer, and has only a small number of dma buffers. + */ +static GLboolean choose_render( struct vertex_buffer *VB, int bufsz ) +{ + int nr_prims = 0; + int nr_rprims = 0; + int nr_rverts = 0; + int rprim = 0; + int i; + + + for (i = 0 ; i < VB->PrimitiveCount ; i++) + { + GLuint prim = VB->Primitive[i].mode; + GLuint length = VB->Primitive[i].count; + + if (!length) + continue; + + if (!hw_prim[prim & PRIM_MODE_MASK]) + return GL_FALSE; + + nr_prims++; + nr_rverts += length * scale_prim[prim & PRIM_MODE_MASK]; + + if (reduced_prim[prim&PRIM_MODE_MASK] != rprim) { + nr_rprims++; + rprim = reduced_prim[prim&PRIM_MODE_MASK]; + } + } + + nr_prims += i / bufsz; + nr_rprims += nr_rverts / bufsz; + + if ((nr_prims > nr_rprims * 2) || + (nr_prims > nr_rprims + 3)) + return GL_FALSE; + + return GL_TRUE; +} + + +static GLboolean i830_run_render( GLcontext *ctx, + struct tnl_pipeline_stage *stage ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i; + /* Don't handle clipping or indexed vertices. + */ + if (imesa->RenderIndex != 0 || + !i830_validate_render( ctx, VB ) || + !choose_render( VB, 200 )) { /* 200 is estimate of nr verts/buf */ + return GL_TRUE; + } + + tnl->Driver.Render.Start( ctx ); + + for (i = 0 ; i < VB->PrimitiveCount ; i++) + { + GLuint prim = VB->Primitive[i].mode; + GLuint start = VB->Primitive[i].start; + GLuint length = VB->Primitive[i].count; + + if (!length) + continue; + + i830_render_tab_verts[prim & PRIM_MODE_MASK]( ctx, start, start + length, + prim ); + } + + tnl->Driver.Render.Finish( ctx ); + + return GL_FALSE; /* finished the pipe */ +} + + +const struct tnl_pipeline_stage _i830_render_stage = +{ + "i830 render", + NULL, + NULL, + NULL, + NULL, + i830_run_render /* run */ +}; diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_screen.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_screen.c new file mode 100644 index 000000000..25def0b6f --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_screen.c @@ -0,0 +1,557 @@ +/************************************************************************** + * + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * **************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_screen.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ + +/** + * \file i830_screen.c + * + * Adapted for use on the I830M by Jeff Hartmann. + * + * \author Keith Whitwell <keith@tungstengraphics.com> + * \author Jeff Hartmann <jhartmann@2d3d.com> + */ + + +#include "glheader.h" +#include "context.h" +#include "matrix.h" +#include "simple_list.h" +#include "framebuffer.h" +#include "renderbuffer.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_state.h" +#include "i830_tex.h" +#include "i830_span.h" +#include "i830_tris.h" +#include "i830_ioctl.h" + +#include "i830_dri.h" + +#include "utils.h" +#include "xmlpool.h" +#include "drirenderbuffer.h" + +PUBLIC const char __driConfigOptions[] = +DRI_CONF_BEGIN + DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_MAX_TEXTURE_UNITS(4,2,4) + DRI_CONF_FORCE_S3TC_ENABLE(false) + DRI_CONF_SECTION_END +DRI_CONF_END; +const GLuint __driNConfigOptions = 2; + +extern const struct dri_extension card_extensions[]; + +static int i830_malloc_proxy_buf(drmBufMapPtr buffers) +{ + char *buffer; + drmBufPtr buf; + int i; + + buffer = ALIGN_MALLOC(I830_DMA_BUF_SZ, 32); + if(buffer == NULL) return -1; + for(i = 0; i < I830_DMA_BUF_NR; i++) { + buf = &(buffers->list[i]); + buf->address = (drmAddress)buffer; + } + + return 0; +} + +static drmBufMapPtr i830_create_empty_buffers(void) +{ + drmBufMapPtr retval; + + retval = (drmBufMapPtr)ALIGN_MALLOC(sizeof(drmBufMap), 32); + if(retval == NULL) return NULL; + memset(retval, 0, sizeof(drmBufMap)); + retval->list = (drmBufPtr)ALIGN_MALLOC(sizeof(drmBuf) * I830_DMA_BUF_NR, 32); + if(retval->list == NULL) { + FREE(retval); + return NULL; + } + + memset(retval->list, 0, sizeof(drmBuf) * I830_DMA_BUF_NR); + return retval; +} + +static void i830PrintDRIInfo(i830ScreenPrivate *i830Screen, + __DRIscreenPrivate *sPriv, + I830DRIPtr gDRIPriv) +{ + GLuint size = (gDRIPriv->ringSize + + i830Screen->textureSize + + i830Screen->depth.size + + i830Screen->back.size + + sPriv->fbSize + + I830_DMA_BUF_NR * I830_DMA_BUF_SZ + + 32768 /* Context Memory */ + + 16*4096 /* Ring buffer */ + + 64*1024 /* Scratch buffer */ + + 4096 /* Cursor */); + GLuint size_low = (gDRIPriv->ringSize + + i830Screen->textureSize + + sPriv->fbSize + + I830_DMA_BUF_NR * I830_DMA_BUF_SZ + + 32768 /* Context Memory */ + + 16*4096 /* Ring buffer */ + + 64*1024 /* Scratch buffer */); + + fprintf(stderr, "\nFront size : 0x%x\n", sPriv->fbSize); + fprintf(stderr, "Front offset : 0x%x\n", i830Screen->fbOffset); + fprintf(stderr, "Back size : 0x%x\n", i830Screen->back.size); + fprintf(stderr, "Back offset : 0x%x\n", i830Screen->backOffset); + fprintf(stderr, "Depth size : 0x%x\n", i830Screen->depth.size); + fprintf(stderr, "Depth offset : 0x%x\n", i830Screen->depthOffset); + fprintf(stderr, "Texture size : 0x%x\n", i830Screen->textureSize); + fprintf(stderr, "Texture offset : 0x%x\n", i830Screen->textureOffset); + fprintf(stderr, "Ring offset : 0x%x\n", gDRIPriv->ringOffset); + fprintf(stderr, "Ring size : 0x%x\n", gDRIPriv->ringSize); + fprintf(stderr, "Memory : 0x%x\n", gDRIPriv->mem); + fprintf(stderr, "Used Memory : low(0x%x) high(0x%x)\n", size_low, size); +} + +static GLboolean i830InitDriver(__DRIscreenPrivate *sPriv) +{ + i830ScreenPrivate *i830Screen; + I830DRIPtr gDRIPriv = (I830DRIPtr)sPriv->pDevPriv; + PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension = + (PFNGLXSCRENABLEEXTENSIONPROC) (*dri_interface->getProcAddress("glxEnableExtension")); + void * const psc = sPriv->psc->screenConfigs; + + if (sPriv->devPrivSize != sizeof(I830DRIRec)) { + fprintf(stderr,"\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* Allocate the private area */ + i830Screen = (i830ScreenPrivate *)CALLOC(sizeof(i830ScreenPrivate)); + if (!i830Screen) { + fprintf(stderr,"\nERROR! Allocating private area failed\n"); + return GL_FALSE; + } + + /* parse information in __driConfigOptions */ + driParseOptionInfo (&i830Screen->optionCache, + __driConfigOptions, __driNConfigOptions); + + + i830Screen->driScrnPriv = sPriv; + sPriv->private = (void *)i830Screen; + + i830Screen->deviceID = gDRIPriv->deviceID; + i830Screen->width = gDRIPriv->width; + i830Screen->height = gDRIPriv->height; + i830Screen->mem = gDRIPriv->mem; + i830Screen->cpp = gDRIPriv->cpp; + i830Screen->fbStride = gDRIPriv->fbStride; + i830Screen->fbOffset = gDRIPriv->fbOffset; + + switch (gDRIPriv->bitsPerPixel) { + case 15: i830Screen->fbFormat = DV_PF_555; break; + case 16: i830Screen->fbFormat = DV_PF_565; break; + case 32: i830Screen->fbFormat = DV_PF_8888; break; + } + + i830Screen->backOffset = gDRIPriv->backOffset; + i830Screen->depthOffset = gDRIPriv->depthOffset; + i830Screen->backPitch = gDRIPriv->auxPitch; + i830Screen->backPitchBits = gDRIPriv->auxPitchBits; + i830Screen->textureOffset = gDRIPriv->textureOffset; + i830Screen->textureSize = gDRIPriv->textureSize; + i830Screen->logTextureGranularity = gDRIPriv->logTextureGranularity; + + + i830Screen->bufs = i830_create_empty_buffers(); + if(i830Screen->bufs == NULL) { + fprintf(stderr,"\nERROR: Failed to create empty buffers in %s \n", + __FUNCTION__); + FREE(i830Screen); + return GL_FALSE; + } + + /* Check if you need to create a fake buffer */ + if(i830_check_copy(sPriv->fd) == 1) { + i830_malloc_proxy_buf(i830Screen->bufs); + i830Screen->use_copy_buf = 1; + } else { + i830Screen->use_copy_buf = 0; + } + + i830Screen->back.handle = gDRIPriv->backbuffer; + i830Screen->back.size = gDRIPriv->backbufferSize; + + if (drmMap(sPriv->fd, + i830Screen->back.handle, + i830Screen->back.size, + (drmAddress *)&i830Screen->back.map) != 0) { + fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n", + __LINE__, __FUNCTION__, __FILE__); + FREE(i830Screen); + sPriv->private = NULL; + return GL_FALSE; + } + + i830Screen->depth.handle = gDRIPriv->depthbuffer; + i830Screen->depth.size = gDRIPriv->depthbufferSize; + + if (drmMap(sPriv->fd, + i830Screen->depth.handle, + i830Screen->depth.size, + (drmAddress *)&i830Screen->depth.map) != 0) { + fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n", + __LINE__, __FUNCTION__, __FILE__); + FREE(i830Screen); + drmUnmap(i830Screen->back.map, i830Screen->back.size); + sPriv->private = NULL; + return GL_FALSE; + } + + i830Screen->tex.handle = gDRIPriv->textures; + i830Screen->tex.size = gDRIPriv->textureSize; + + if (drmMap(sPriv->fd, + i830Screen->tex.handle, + i830Screen->tex.size, + (drmAddress *)&i830Screen->tex.map) != 0) { + fprintf(stderr, "\nERROR: line %d, Function %s, File %s\n", + __LINE__, __FUNCTION__, __FILE__); + FREE(i830Screen); + drmUnmap(i830Screen->back.map, i830Screen->back.size); + drmUnmap(i830Screen->depth.map, i830Screen->depth.size); + sPriv->private = NULL; + return GL_FALSE; + } + + i830Screen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + + if (0) i830PrintDRIInfo(i830Screen, sPriv, gDRIPriv); + + i830Screen->drmMinor = sPriv->drmMinor; + + if (sPriv->drmMinor >= 3) { + int ret; + drmI830GetParam gp; + + gp.param = I830_PARAM_IRQ_ACTIVE; + gp.value = &i830Screen->irq_active; + + ret = drmCommandWriteRead( sPriv->fd, DRM_I830_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmI830GetParam: %d\n", ret); + return GL_FALSE; + } + } + +#if 0 + if (sPriv->drmMinor >= 3) { + int ret; + drmI830SetParam sp; + + sp.param = I830_SETPARAM_PERF_BOXES; + sp.value = (getenv("I830_DO_BOXES") != 0); + + ret = drmCommandWrite( sPriv->fd, DRM_I830_SETPARAM, + &sp, sizeof(sp)); + if (ret) + fprintf(stderr, "Couldn't set perfboxes: %d\n", ret); + } +#endif + + if ( glx_enable_extension != NULL ) { + (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" ); + } + + return GL_TRUE; +} + + +static void i830DestroyScreen(__DRIscreenPrivate *sPriv) +{ + i830ScreenPrivate *i830Screen = (i830ScreenPrivate *)sPriv->private; + + /* Need to unmap all the bufs and maps here: + */ + drmUnmap(i830Screen->back.map, i830Screen->back.size); + drmUnmap(i830Screen->depth.map, i830Screen->depth.size); + drmUnmap(i830Screen->tex.map, i830Screen->tex.size); + FREE(i830Screen); + sPriv->private = NULL; +} + + +static GLboolean i830CreateBuffer(__DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap ) +{ + i830ScreenPrivate *screen = (i830ScreenPrivate *) driScrnPriv->private; + + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { +#if 0 + GLboolean swStencil = (mesaVis->stencilBits > 0 && + mesaVis->depthBits != 24); +#else + GLboolean swStencil = mesaVis->stencilBits > 0; +#endif + +#if 0 + driDrawPriv->driverPrivate = (void *) + _mesa_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + swStencil, + mesaVis->accumRedBits > 0, + GL_FALSE /* s/w alpha planes */); +#else + struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis); + + { + driRenderbuffer *frontRb + = driNewRenderbuffer(GL_RGBA, screen->cpp, + /*screen->frontOffset*/0, screen->backPitch); + i830SetSpanFunctions(frontRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontRb->Base); + } + + if (mesaVis->doubleBufferMode) { + driRenderbuffer *backRb + = driNewRenderbuffer(GL_RGBA, screen->cpp, + screen->backOffset, screen->backPitch); + i830SetSpanFunctions(backRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backRb->Base); + } + + if (mesaVis->depthBits == 16) { + driRenderbuffer *depthRb + = driNewRenderbuffer(GL_DEPTH_COMPONENT16, screen->cpp, + screen->depthOffset, screen->backPitch); + i830SetSpanFunctions(depthRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + } + else if (mesaVis->depthBits == 24) { + if (mesaVis->stencilBits == 8) { + driRenderbuffer *depthRb + = driNewRenderbuffer(GL_DEPTH_COMPONENT24, screen->cpp, + screen->depthOffset, screen->backPitch); + i830SetSpanFunctions(depthRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + } + else { + /* not really 32-bit Z, but use GL_DEPTH_COMPONENT32 anyway */ + driRenderbuffer *depthRb + = driNewRenderbuffer(GL_DEPTH_COMPONENT32, screen->cpp, + screen->depthOffset, screen->backPitch); + i830SetSpanFunctions(depthRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base); + } + } + + if (mesaVis->stencilBits > 0 && !swStencil) { + driRenderbuffer *stencilRb + = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT, screen->cpp, + screen->depthOffset, screen->backPitch); + i830SetSpanFunctions(stencilRb, mesaVis); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base); + } + + _mesa_add_soft_renderbuffers(fb, + GL_FALSE, /* color */ + GL_FALSE, /* depth */ + swStencil, + mesaVis->accumRedBits > 0, + GL_FALSE, /* alpha */ + GL_FALSE /* aux */); + driDrawPriv->driverPrivate = (void *) fb; +#endif + + return (driDrawPriv->driverPrivate != NULL); + } +} + +static void i830DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + +static const struct __DriverAPIRec i830API = { + .InitDriver = i830InitDriver, + .DestroyScreen = i830DestroyScreen, + .CreateContext = i830CreateContext, + .DestroyContext = i830DestroyContext, + .CreateBuffer = i830CreateBuffer, + .DestroyBuffer = i830DestroyBuffer, + .SwapBuffers = i830SwapBuffers, + .MakeCurrent = i830MakeCurrent, + .UnbindContext = i830UnbindContext, + .GetSwapInfo = NULL, + .GetMSC = NULL, + .WaitForMSC = NULL, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL +}; + + +static __GLcontextModes * +i830FillInModes( unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer ) +{ + __GLcontextModes * modes; + __GLcontextModes * m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the MGA driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + u_int8_t depth_bits_array[2]; + u_int8_t stencil_bits_array[2]; + + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1; + back_buffer_factor = (have_back_buffer) ? 3 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + if ( pixel_bits == 16 ) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) ); + m = modes; + if ( ! driFillInModes( & m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, depth_buffer_factor, + back_buffer_modes, back_buffer_factor, + GLX_TRUE_COLOR ) ) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + + /* There's no direct color modes on i830? */ + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for ( m = modes ; m != NULL ; m = m->next ) { + if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC +void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes ** driver_modes ) + +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 1, 0, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 3, 0 }; + + dri_interface = interface; + + if ( ! driCheckDriDdxDrmVersions2( "i830", + dri_version, & dri_expected, + ddx_version, & ddx_expected, + drm_version, & drm_expected ) ) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &i830API); + if ( psp != NULL ) { + I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; + *driver_modes = i830FillInModes( dri_priv->cpp * 8, + (dri_priv->cpp == 2) ? 16 : 24, + (dri_priv->cpp == 2) ? 0 : 8, + (dri_priv->backOffset != dri_priv->depthOffset) ); + + /* Calling driInitExtensions here, with a NULL context pointer, does not actually + * enable the extensions. It just makes sure that all the dispatch offsets for all + * the extensions that *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is called, but we can't + * enable the extensions until we have a context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); + } + + return (void *) psp; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_screen.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_screen.h new file mode 100644 index 000000000..edbe719e0 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_screen.h @@ -0,0 +1,113 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * Adapted for use on the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> + */ + +#ifndef _I830_INIT_H_ +#define _I830_INIT_H_ + +#include <sys/time.h> +#include "dri_util.h" +#include "xmlconfig.h" + + +typedef struct { + drm_handle_t handle; + drmSize size; + char *map; +} i830Region, *i830RegionPtr; + +typedef struct +{ + + i830Region front; + i830Region back; + i830Region depth; + i830Region tex; + + int deviceID; + int width; + int height; + int mem; + + int cpp; /* for front and back buffers */ + int bitsPerPixel; + + int fbFormat; + int fbOffset; + int fbStride; + + int backOffset; + int depthOffset; + + int backPitch; + int backPitchBits; + + int textureOffset; + int textureSize; + int logTextureGranularity; + + __DRIscreenPrivate *driScrnPriv; + drmBufMapPtr bufs; + int use_copy_buf; + unsigned int sarea_priv_offset; + + int drmMinor; + int irq_active; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; +}i830ScreenPrivate; + + +extern GLboolean +i830CreateContext( const __GLcontextModes *mesaVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ); + +extern void +i830DestroyContext(__DRIcontextPrivate *driContextPriv); + +extern GLboolean +i830UnbindContext(__DRIcontextPrivate *driContextPriv); + +extern GLboolean +i830MakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv); + +extern void +i830SwapBuffers(__DRIdrawablePrivate *driDrawPriv); + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_span.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_span.c new file mode 100644 index 000000000..4a86784e8 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_span.c @@ -0,0 +1,427 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_span.c,v 1.4 2002/12/10 01:26:53 dawes Exp $ */ + +/** + * \file i830_span.c + * + * Heavily based on the I810 driver, which was written by Keith Whitwell. + * + * \author Jeff Hartmann <jhartmann@2d3d.com> + * \author Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "colormac.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_span.h" +#include "i830_ioctl.h" +#include "swrast/swrast.h" + + +#define DBG 0 + +#define LOCAL_VARS \ + i830ContextPtr imesa = I830_CONTEXT(ctx); \ + __DRIdrawablePrivate *dPriv = imesa->mesa_drawable; \ + i830ScreenPrivate *i830Screen = imesa->i830Screen; \ + GLuint pitch = i830Screen->backPitch * i830Screen->cpp; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(imesa->drawMap + \ + dPriv->x * i830Screen->cpp + \ + dPriv->y * pitch); \ + char *read_buf = (char *)(imesa->readMap + \ + dPriv->x * i830Screen->cpp + \ + dPriv->y * pitch); \ + GLushort p; \ + (void) read_buf; (void) buf; (void) p + +#define LOCAL_DEPTH_VARS \ + i830ContextPtr imesa = I830_CONTEXT(ctx); \ + __DRIdrawablePrivate *dPriv = imesa->mesa_drawable; \ + i830ScreenPrivate *i830Screen = imesa->i830Screen; \ + GLuint pitch = i830Screen->backPitch * i830Screen->cpp; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(i830Screen->depth.map + \ + dPriv->x * i830Screen->cpp + \ + dPriv->y * pitch) + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + +#define INIT_MONO_PIXEL(p,color)\ + p = PACK_COLOR_565(color[0],color[1],color[2]) + +#define Y_FLIP(_y) (height - _y - 1) + +#define HW_LOCK() + +#define HW_UNLOCK() + +/* 16 bit, 565 rgb color spanline and pixel functions + */ +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = ( (((int)r & 0xf8) << 8) | \ + (((int)g & 0xfc) << 3) | \ + (((int)b & 0xf8) >> 3)) +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \ + rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \ + rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \ + rgba[3] = 255; \ +} while(0) + +#define TAG(x) i830##x##_565 +#include "spantmp.h" + +/* 15 bit, 555 rgb color spanline and pixel functions + */ +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \ + ((g & 0xf8) << 3) | \ + ((b & 0xf8) >> 3)) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = (p >> 7) & 0xf8; \ + rgba[1] = (p >> 3) & 0xf8; \ + rgba[2] = (p << 3) & 0xf8; \ + rgba[3] = 255; \ +} while(0) + +#define TAG(x) i830##x##_555 +#include "spantmp.h" + +/* 16 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + _x*2 + _y*pitch); + + +#define TAG(x) i830##x##_16 +#include "depthtmp.h" + + +#undef LOCAL_VARS +#define LOCAL_VARS \ + i830ContextPtr imesa = I830_CONTEXT(ctx); \ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ + i830ScreenPrivate *i830Screen = imesa->i830Screen; \ + GLuint pitch = i830Screen->backPitch * i830Screen->cpp; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(imesa->drawMap + \ + dPriv->x * i830Screen->cpp + \ + dPriv->y * pitch); \ + char *read_buf = (char *)(imesa->readMap + \ + dPriv->x * i830Screen->cpp + \ + dPriv->y * pitch); \ + GLuint p = I830_CONTEXT( ctx )->MonoColor; \ + (void) read_buf; (void) buf; (void) p + +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p,color)\ + p = PACK_COLOR_888(color[0],color[1],color[2]) + +/* 32 bit, 8888 argb color spanline and pixel functions + */ +#define WRITE_RGBA(_x, _y, r, g, b, a) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = ((r << 16) | \ + (g << 8) | \ + (b << 0) | \ + (a << 24) ) + +#define WRITE_PIXEL(_x, _y, p) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = p + + +#define READ_RGBA(rgba, _x, _y) \ + do { \ + GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = (p >> 24) & 0xff; \ + } while (0) + +#define TAG(x) i830##x##_8888 +#include "spantmp.h" + +/* 24 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = 0xffffff & d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xffffff; + +#define TAG(x) i830##x##_24 +#include "depthtmp.h" + +/* 24/8 bit interleaved depth/stencil functions + */ +#define WRITE_DEPTH( _x, _y, d ) { \ + GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \ + tmp &= 0xff000000; \ + tmp |= (d) & 0xffffff; \ + *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \ +} + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xffffff; + + +#define TAG(x) i830##x##_24_8 +#include "depthtmp.h" + +#define WRITE_STENCIL( _x, _y, d ) { \ + GLuint tmp = *(GLuint *)(buf + _x*4 + _y*pitch); \ + tmp &= 0xffffff; \ + tmp |= (d<<24); \ + *(GLuint *)(buf + _x*4 + _y*pitch) = tmp; \ +} + +#define READ_STENCIL( d, _x, _y ) \ + d = *(GLuint *)(buf + _x*4 + _y*pitch) >> 24; + +#define TAG(x) i830##x##_24_8 +#include "stenciltmp.h" + +/* + * This function is called to specify which buffer to read and write + * for software rasterization (swrast) fallbacks. This doesn't necessarily + * correspond to glDrawBuffer() or glReadBuffer() calls. + */ +static void i830SetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer, + GLuint bufferBit) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + assert( (colorBuffer == imesa->driDrawable->driverPrivate) + || (colorBuffer == imesa->driReadable->driverPrivate) ); + + imesa->mesa_drawable = (colorBuffer == imesa->driDrawable->driverPrivate) + ? imesa->driDrawable : imesa->driReadable; + + if (bufferBit == BUFFER_BIT_FRONT_LEFT) { + imesa->drawMap = (char *)imesa->driScreen->pFB; + imesa->readMap = (char *)imesa->driScreen->pFB; + } else if (bufferBit == BUFFER_BIT_BACK_LEFT) { + imesa->drawMap = imesa->i830Screen->back.map; + imesa->readMap = imesa->i830Screen->back.map; + } else { + ASSERT(0); + } +} + + + +/* Move locking out to get reasonable span performance. + */ +void i830SpanRenderStart( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + I830_FIREVERTICES(imesa); + LOCK_HARDWARE(imesa); + i830RegetLockQuiescent( imesa ); +} + +void i830SpanRenderFinish( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + _swrast_flush( ctx ); + UNLOCK_HARDWARE( imesa ); +} + +void i830DDInitSpanFuncs( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + i830ScreenPrivate *i830Screen = imesa->i830Screen; + + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + + swdd->SetBuffer = i830SetBuffer; + + switch (i830Screen->fbFormat) { + case DV_PF_555: +#if 0 + swdd->WriteRGBASpan = i830WriteRGBASpan_555; + swdd->WriteRGBSpan = i830WriteRGBSpan_555; + swdd->WriteMonoRGBASpan = i830WriteMonoRGBASpan_555; + swdd->WriteRGBAPixels = i830WriteRGBAPixels_555; + swdd->WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_555; + swdd->ReadRGBASpan = i830ReadRGBASpan_555; + swdd->ReadRGBAPixels = i830ReadRGBAPixels_555; + swdd->ReadDepthSpan = i830ReadDepthSpan_16; + swdd->WriteDepthSpan = i830WriteDepthSpan_16; + swdd->ReadDepthPixels = i830ReadDepthPixels_16; + swdd->WriteDepthPixels = i830WriteDepthPixels_16; +#endif + break; + + case DV_PF_565: +#if 0 + swdd->WriteRGBASpan = i830WriteRGBASpan_565; + swdd->WriteRGBSpan = i830WriteRGBSpan_565; + swdd->WriteMonoRGBASpan = i830WriteMonoRGBASpan_565; + swdd->WriteRGBAPixels = i830WriteRGBAPixels_565; + swdd->WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_565; + swdd->ReadRGBASpan = i830ReadRGBASpan_565; + swdd->ReadRGBAPixels = i830ReadRGBAPixels_565; + swdd->ReadDepthSpan = i830ReadDepthSpan_16; + swdd->WriteDepthSpan = i830WriteDepthSpan_16; + swdd->ReadDepthPixels = i830ReadDepthPixels_16; + swdd->WriteDepthPixels = i830WriteDepthPixels_16; +#endif + break; + + case DV_PF_8888: +#if 0 + swdd->WriteRGBASpan = i830WriteRGBASpan_8888; + swdd->WriteRGBSpan = i830WriteRGBSpan_8888; + swdd->WriteMonoRGBASpan = i830WriteMonoRGBASpan_8888; + swdd->WriteRGBAPixels = i830WriteRGBAPixels_8888; + swdd->WriteMonoRGBAPixels = i830WriteMonoRGBAPixels_8888; + swdd->ReadRGBASpan = i830ReadRGBASpan_8888; + swdd->ReadRGBAPixels = i830ReadRGBAPixels_8888; +#endif + + if(imesa->hw_stencil) { +#if 0 + swdd->ReadDepthSpan = i830ReadDepthSpan_24_8; + swdd->WriteDepthSpan = i830WriteDepthSpan_24_8; + swdd->ReadDepthPixels = i830ReadDepthPixels_24_8; + swdd->WriteDepthPixels = i830WriteDepthPixels_24_8; + swdd->WriteStencilSpan = i830WriteStencilSpan_24_8; + swdd->ReadStencilSpan = i830ReadStencilSpan_24_8; + swdd->WriteStencilPixels = i830WriteStencilPixels_24_8; + swdd->ReadStencilPixels = i830ReadStencilPixels_24_8; +#endif + } else { +#if 0 + swdd->ReadDepthSpan = i830ReadDepthSpan_24; + swdd->WriteDepthSpan = i830WriteDepthSpan_24; + swdd->ReadDepthPixels = i830ReadDepthPixels_24; + swdd->WriteDepthPixels = i830WriteDepthPixels_24; +#endif + } + break; + } + + swdd->SpanRenderStart = i830SpanRenderStart; + swdd->SpanRenderFinish = i830SpanRenderFinish; +} + + +/** + * Plug in the Get/Put routines for the given driRenderbuffer. + */ +void +i830SetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis) +{ + if (drb->Base.InternalFormat == GL_RGBA) { + if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) { + drb->Base.GetRow = i830ReadRGBASpan_555; + drb->Base.GetValues = i830ReadRGBAPixels_555; + drb->Base.PutRow = i830WriteRGBASpan_555; + drb->Base.PutRowRGB = i830WriteRGBSpan_555; + drb->Base.PutMonoRow = i830WriteMonoRGBASpan_555; + drb->Base.PutValues = i830WriteRGBAPixels_555; + drb->Base.PutMonoValues = i830WriteMonoRGBAPixels_555; + } + else if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) { + drb->Base.GetRow = i830ReadRGBASpan_565; + drb->Base.GetValues = i830ReadRGBAPixels_565; + drb->Base.PutRow = i830WriteRGBASpan_565; + drb->Base.PutRowRGB = i830WriteRGBSpan_565; + drb->Base.PutMonoRow = i830WriteMonoRGBASpan_565; + drb->Base.PutValues = i830WriteRGBAPixels_565; + drb->Base.PutMonoValues = i830WriteMonoRGBAPixels_565; + } + else { + assert(vis->redBits == 8); + assert(vis->greenBits == 8); + assert(vis->blueBits == 8); + drb->Base.GetRow = i830ReadRGBASpan_8888; + drb->Base.GetValues = i830ReadRGBAPixels_8888; + drb->Base.PutRow = i830WriteRGBASpan_8888; + drb->Base.PutRowRGB = i830WriteRGBSpan_8888; + drb->Base.PutMonoRow = i830WriteMonoRGBASpan_8888; + drb->Base.PutValues = i830WriteRGBAPixels_8888; + drb->Base.PutMonoValues = i830WriteMonoRGBAPixels_8888; + } + } + else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) { + drb->Base.GetRow = i830ReadDepthSpan_16; + drb->Base.GetValues = i830ReadDepthPixels_16; + drb->Base.PutRow = i830WriteDepthSpan_16; + drb->Base.PutMonoRow = i830WriteMonoDepthSpan_16; + drb->Base.PutValues = i830WriteDepthPixels_16; + drb->Base.PutMonoValues = NULL; + } + else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) { + drb->Base.GetRow = i830ReadDepthSpan_24_8; + drb->Base.GetValues = i830ReadDepthPixels_24_8; + drb->Base.PutRow = i830WriteDepthSpan_24_8; + drb->Base.PutMonoRow = i830WriteMonoDepthSpan_24_8; + drb->Base.PutValues = i830WriteDepthPixels_24_8; + drb->Base.PutMonoValues = NULL; + } + else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT32) { + /* not _really_ 32-bit Z */ + drb->Base.GetRow = i830ReadDepthSpan_24; + drb->Base.GetValues = i830ReadDepthPixels_24; + drb->Base.PutRow = i830WriteDepthSpan_24; + drb->Base.PutMonoRow = i830WriteMonoDepthSpan_24; + drb->Base.PutValues = i830WriteDepthPixels_24; + drb->Base.PutMonoValues = NULL; + } + else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) { + drb->Base.GetRow = i830ReadStencilSpan_24_8; + drb->Base.GetValues = i830ReadStencilPixels_24_8; + drb->Base.PutRow = i830WriteStencilSpan_24_8; + drb->Base.PutMonoRow = i830WriteMonoStencilSpan_24_8; + drb->Base.PutValues = i830WriteStencilPixels_24_8; + drb->Base.PutMonoValues = NULL; + } +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_span.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_span.h new file mode 100644 index 000000000..4b8341971 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_span.h @@ -0,0 +1,51 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_span.h,v 1.2 2002/09/11 00:29:26 dawes Exp $ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef _I830_SPAN_H +#define _I830_SPAN_H + +#include "drirenderbuffer.h" + +extern void i830DDInitSpanFuncs( GLcontext *ctx ); + +extern void i830SpanRenderFinish( GLcontext *ctx ); +extern void i830SpanRenderStart( GLcontext *ctx ); + +extern void +i830SetSpanFunctions(driRenderbuffer *rb, const GLvisual *vis); + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_state.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_state.c new file mode 100644 index 000000000..615348544 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_state.c @@ -0,0 +1,1707 @@ +/************************************************************************** + +Copyright 2001 2d3d Inc., Delray Beach, FL + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.c,v 1.6 2003/01/28 22:47:06 dawes Exp $ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#include "glheader.h" +#include "buffers.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" + +#include "texmem.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_state.h" +#include "i830_tex.h" +#include "i830_tris.h" +#include "i830_ioctl.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + +static __inline__ GLuint i830PackColor(GLuint format, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + switch (format) { + case DV_PF_555: + return I830PACKCOLOR1555(r,g,b,a); + case DV_PF_565: + return I830PACKCOLOR565(r,g,b); + case DV_PF_8888: + return I830PACKCOLOR8888(r,g,b,a); + default: + fprintf(stderr, "unknown format %d\n", (int)format); + return 0; + } +} + +static void i830StencilFunc(GLcontext *ctx, GLenum func, GLint ref, + GLuint mask) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int test = 0; + + mask = mask & 0xff; + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(func), ref, mask); + + switch(func) { + case GL_NEVER: + test = COMPAREFUNC_NEVER; + break; + case GL_LESS: + test = COMPAREFUNC_LESS; + break; + case GL_LEQUAL: + test = COMPAREFUNC_LEQUAL; + break; + case GL_GREATER: + test = COMPAREFUNC_GREATER; + break; + case GL_GEQUAL: + test = COMPAREFUNC_GEQUAL; + break; + case GL_NOTEQUAL: + test = COMPAREFUNC_NOTEQUAL; + break; + case GL_EQUAL: + test = COMPAREFUNC_EQUAL; + break; + case GL_ALWAYS: + test = COMPAREFUNC_ALWAYS; + break; + default: + return; + } + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; + imesa->Setup[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(mask)); + imesa->Setup[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | + ENABLE_STENCIL_TEST_FUNC_MASK); + imesa->Setup[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_REF_VALUE(ref) | + STENCIL_TEST_FUNC(test)); +} + +static void i830StencilMask(GLcontext *ctx, GLuint mask) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask); + + mask = mask & 0xff; + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; + imesa->Setup[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(mask)); +} + +static void i830StencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, + GLenum zpass) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int fop, dfop, dpop; + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(fail), + _mesa_lookup_enum_by_nr(zfail), + _mesa_lookup_enum_by_nr(zpass)); + + fop = 0; dfop = 0; dpop = 0; + + switch(fail) { + case GL_KEEP: + fop = STENCILOP_KEEP; + break; + case GL_ZERO: + fop = STENCILOP_ZERO; + break; + case GL_REPLACE: + fop = STENCILOP_REPLACE; + break; + case GL_INCR: + fop = STENCILOP_INCRSAT; + break; + case GL_DECR: + fop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + fop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + fop = STENCILOP_DECR; + break; + case GL_INVERT: + fop = STENCILOP_INVERT; + break; + default: + break; + } + switch(zfail) { + case GL_KEEP: + dfop = STENCILOP_KEEP; + break; + case GL_ZERO: + dfop = STENCILOP_ZERO; + break; + case GL_REPLACE: + dfop = STENCILOP_REPLACE; + break; + case GL_INCR: + dfop = STENCILOP_INCRSAT; + break; + case GL_DECR: + dfop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + dfop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + dfop = STENCILOP_DECR; + break; + case GL_INVERT: + dfop = STENCILOP_INVERT; + break; + default: + break; + } + switch(zpass) { + case GL_KEEP: + dpop = STENCILOP_KEEP; + break; + case GL_ZERO: + dpop = STENCILOP_ZERO; + break; + case GL_REPLACE: + dpop = STENCILOP_REPLACE; + break; + case GL_INCR: + dpop = STENCILOP_INCRSAT; + break; + case GL_DECR: + dpop = STENCILOP_DECRSAT; + break; + case GL_INCR_WRAP: + dpop = STENCILOP_INCR; + break; + case GL_DECR_WRAP: + dpop = STENCILOP_DECR; + break; + case GL_INVERT: + dpop = STENCILOP_INVERT; + break; + default: + break; + } + + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); + imesa->Setup[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(fop) | + STENCIL_PASS_DEPTH_FAIL_OP(dfop) | + STENCIL_PASS_DEPTH_PASS_OP(dpop)); +} + +static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int test = 0; + GLuint refByte = (GLint) (ref * 255.0); + + switch(func) { + case GL_NEVER: + test = COMPAREFUNC_NEVER; + break; + case GL_LESS: + test = COMPAREFUNC_LESS; + break; + case GL_LEQUAL: + test = COMPAREFUNC_LEQUAL; + break; + case GL_GREATER: + test = COMPAREFUNC_GREATER; + break; + case GL_GEQUAL: + test = COMPAREFUNC_GEQUAL; + break; + case GL_NOTEQUAL: + test = COMPAREFUNC_NOTEQUAL; + break; + case GL_EQUAL: + test = COMPAREFUNC_EQUAL; + break; + case GL_ALWAYS: + test = COMPAREFUNC_ALWAYS; + break; + default: + return; + } + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK; + imesa->Setup[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC | + ENABLE_ALPHA_REF_VALUE | + ALPHA_TEST_FUNC(test) | + ALPHA_REF_VALUE(refByte)); +} + +/* This function makes sure that the proper enables are + * set for LogicOp, Independant Alpha Blend, and Blending. + * It needs to be called from numerous places where we + * could change the LogicOp or Independant Alpha Blend without subsequent + * calls to glEnable. + */ +static void i830EvalLogicOpBlendState(GLcontext *ctx) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | + ENABLE_LOGIC_OP_MASK); + imesa->Setup[I830_CTXREG_IALPHAB] &= ~ENABLE_INDPT_ALPHA_BLEND; + + if (ctx->Color.ColorLogicOpEnabled) { + imesa->Setup[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | + ENABLE_LOGIC_OP); + imesa->Setup[I830_CTXREG_IALPHAB] |= DISABLE_INDPT_ALPHA_BLEND; + } else if (ctx->Color.BlendEnabled) { + imesa->Setup[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND | + DISABLE_LOGIC_OP); + + /* If the alpha blend state does not match the color blend state, + * enable independent alpha blending. Otherwise, leave it disabled + * and the hardware will use the color blend state for both. + */ + + if ( 0 && (imesa->Setup[I830_CTXREG_IALPHAB] & BLEND_STATE_MASK) + != (imesa->Setup[I830_CTXREG_STATE1] & BLEND_STATE_MASK) ) { + imesa->Setup[I830_CTXREG_IALPHAB] |= ENABLE_INDPT_ALPHA_BLEND; + } else { + imesa->Setup[I830_CTXREG_IALPHAB] |= DISABLE_INDPT_ALPHA_BLEND; + } + } else { + imesa->Setup[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | + DISABLE_LOGIC_OP); + imesa->Setup[I830_CTXREG_IALPHAB] |= DISABLE_INDPT_ALPHA_BLEND; + } +} + +static void i830BlendColor(GLcontext *ctx, const GLfloat color[4]) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLubyte r, g, b, a; + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + FLOAT_COLOR_TO_UBYTE_COLOR(r, color[RCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(g, color[GCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(b, color[BCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(a, color[ACOMP]); + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_BLENDCOLR] = ((a << 24) | + (r << 16) | + (g << 8) | + b); +} + +/** + * Calculate the hardware blend factor setting. This same function is used + * for source and destination of both alpha and RGB. + * + * \returns + * The hardware register value for the specified blend factor. This value + * will need to be shifted into the correct position for either source or + * destination factor. + * + * \todo + * Since the two cases where source and destination are handled differently + * are essentially error cases, they should never happen. Determine if these + * cases can be removed. + */ +static int blend_factor( GLenum factor, GLboolean is_src ) +{ + int func; + + switch( factor ) { + case GL_ZERO: + func = BLENDFACT_ZERO; + break; + case GL_ONE: + func = BLENDFACT_ONE; + break; + case GL_SRC_COLOR: + func = BLENDFACT_SRC_COLR; + break; + case GL_ONE_MINUS_SRC_COLOR: + func = BLENDFACT_INV_SRC_COLR; + break; + case GL_SRC_ALPHA: + func = BLENDFACT_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + func = BLENDFACT_INV_SRC_ALPHA; + break; + case GL_DST_ALPHA: + func = BLENDFACT_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + func = BLENDFACT_INV_DST_ALPHA; + break; + case GL_DST_COLOR: + func = BLENDFACT_DST_COLR; + break; + case GL_ONE_MINUS_DST_COLOR: + func = BLENDFACT_INV_DST_COLR; + break; + case GL_SRC_ALPHA_SATURATE: + func = (is_src) ? BLENDFACT_SRC_ALPHA_SATURATE : BLENDFACT_ZERO; + break; + case GL_CONSTANT_COLOR: + func = BLENDFACT_CONST_COLOR; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + func = BLENDFACT_INV_CONST_COLOR; + break; + case GL_CONSTANT_ALPHA: + func = BLENDFACT_CONST_ALPHA; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + func = BLENDFACT_INV_CONST_ALPHA; + break; + default: + func = (is_src) ? BLENDFACT_ONE : BLENDFACT_ZERO; + } + + return func; +} + + +/** + * Sets both the blend equation (called "function" in i830 docs) and the + * blend function (called "factor" in i830 docs). This is done in a single + * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX) + * change the interpretation of the blend function. + */ + +static void i830_set_blend_state( GLcontext * ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int funcA; + int funcRGB; + int eqnA; + int eqnRGB; + + + funcRGB = SRC_BLND_FACT( blend_factor( ctx->Color.BlendSrcRGB, GL_TRUE ) ) + | DST_BLND_FACT( blend_factor( ctx->Color.BlendDstRGB, GL_FALSE ) ); + + switch(ctx->Color.BlendEquationRGB) { + case GL_FUNC_ADD: + eqnRGB = BLENDFUNC_ADD; + break; + case GL_MIN: + eqnRGB = BLENDFUNC_MIN; + funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_MAX: + eqnRGB = BLENDFUNC_MAX; + funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_FUNC_SUBTRACT: + eqnRGB = BLENDFUNC_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + eqnRGB = BLENDFUNC_RVRSE_SUB; + break; + default: + fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n", + __func__, __LINE__, ctx->Color.BlendEquationRGB ); + return; + } + + + funcA = SRC_ABLEND_FACT( blend_factor( ctx->Color.BlendSrcA, GL_TRUE ) ) + | DST_ABLEND_FACT( blend_factor( ctx->Color.BlendDstA, GL_FALSE ) ); + + switch(ctx->Color.BlendEquationA) { + case GL_FUNC_ADD: + eqnA = BLENDFUNC_ADD; + break; + case GL_MIN: + eqnA = BLENDFUNC_MIN; + funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_MAX: + eqnA = BLENDFUNC_MAX; + funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); + break; + case GL_FUNC_SUBTRACT: + eqnA = BLENDFUNC_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + eqnA = BLENDFUNC_RVRSE_SUB; + break; + default: + fprintf( stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n", + __func__, __LINE__, ctx->Color.BlendEquationA ); + return; + } + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + + imesa->Setup[I830_CTXREG_STATE1] = eqnRGB | funcRGB + | STATE3D_MODES_1_CMD + | ENABLE_SRC_BLND_FACTOR | ENABLE_DST_BLND_FACTOR + | ENABLE_COLR_BLND_FUNC; + + imesa->Setup[I830_CTXREG_IALPHAB] = eqnA | funcA + | STATE3D_INDPT_ALPHA_BLEND_CMD + | ENABLE_SRC_ABLEND_FACTOR | ENABLE_DST_ABLEND_FACTOR + | ENABLE_ALPHA_BLENDFUNC; + + + /* This will catch a logicop blend equation. It will also ensure + * independant alpha blend is really in the correct state (either enabled + * or disabled) if blending is already enabled. + */ + + i830EvalLogicOpBlendState(ctx); + + if (0) { + fprintf(stderr, "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n", + __func__, __LINE__, + imesa->Setup[I830_CTXREG_STATE1], + imesa->Setup[I830_CTXREG_IALPHAB], + (ctx->Color.BlendEnabled) ? "en" : "dis"); + } +} + +static void i830BlendEquationSeparate(GLcontext *ctx, + GLenum modeRGB, GLenum modeA) +{ + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s -> %s, %s\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(modeRGB), + _mesa_lookup_enum_by_nr(modeA)); + + (void) modeRGB; + (void) modeA; + i830_set_blend_state( ctx ); +} + + + +static void i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, + GLenum dfactorA ) +{ + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(sfactorRGB), + _mesa_lookup_enum_by_nr(dfactorRGB), + _mesa_lookup_enum_by_nr(sfactorA), + _mesa_lookup_enum_by_nr(dfactorA)); + + (void) sfactorRGB; + (void) dfactorRGB; + (void) sfactorA; + (void) dfactorA; + i830_set_blend_state( ctx ); +} + +static void i830DepthFunc(GLcontext *ctx, GLenum func) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int test = 0; + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + switch(func) { + case GL_NEVER: + test = COMPAREFUNC_NEVER; + break; + case GL_LESS: + test = COMPAREFUNC_LESS; + break; + case GL_LEQUAL: + test = COMPAREFUNC_LEQUAL; + break; + case GL_GREATER: + test = COMPAREFUNC_GREATER; + break; + case GL_GEQUAL: + test = COMPAREFUNC_GEQUAL; + break; + case GL_NOTEQUAL: + test = COMPAREFUNC_NOTEQUAL; + break; + case GL_EQUAL: + test = COMPAREFUNC_EQUAL; + break; + case GL_ALWAYS: + test = COMPAREFUNC_ALWAYS; + break; + default: return; + } + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK; + imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC(test)); +} + +static void i830DepthMask(GLcontext *ctx, GLboolean flag) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag); + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + + imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK; + + if (flag && ctx->Depth.Test) + imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE; + else + imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE; +} + +/* ============================================================= + * Polygon stipple + * + * The i830 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + */ +static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i,j,k; + int active = (ctx->Polygon.StippleFlag && + imesa->reduced_primitive == GL_TRIANGLES); + GLuint newMask; + + if (active) { + I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE); + imesa->StippleSetup[I830_STPREG_ST1] &= ~ST1_ENABLE; + } + + p[0] = mask[12] & 0xf; p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; p[3] |= p[3] << 4; + + for (k = 0 ; k < 8 ; k++) + for (j = 3 ; j >= 0; j--) + for (i = 0 ; i < 4 ; i++, m++) + if (*m != p[j]) { + imesa->hw_stipple = 0; + return; + } + + newMask = (((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | + ((p[3] & 0xf) << 12)); + + + if (newMask == 0xffff || newMask == 0x0) { + /* this is needed to make conform pass */ + imesa->hw_stipple = 0; + return; + } + + imesa->StippleSetup[I830_STPREG_ST1] &= ~0xffff; + imesa->StippleSetup[I830_STPREG_ST1] |= newMask; + imesa->hw_stipple = 1; + + if (active) + imesa->StippleSetup[I830_STPREG_ST1] |= ST1_ENABLE; +} + +static void i830PolygonStippleFallback( GLcontext *ctx, const GLubyte *mask ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + imesa->hw_stipple = 0; + (void) i830PolygonStipple; +} + +/* ============================================================= + * Hardware clipping + */ +static void i830Scissor(GLcontext *ctx, GLint x, GLint y, + GLsizei w, GLsizei h) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int x1 = x; + int y1 = imesa->driDrawable->h - (y + h); + int x2 = x + w - 1; + int y2 = y1 + h - 1; + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__, + x, y, w, h); + + if (x1 < 0) x1 = 0; + if (y1 < 0) y1 = 0; + if (x2 < 0) x2 = 0; + if (y2 < 0) y2 = 0; + + if (x2 >= imesa->i830Screen->width) x2 = imesa->i830Screen->width-1; + if (y2 >= imesa->i830Screen->height) y2 = imesa->i830Screen->height-1; + if (x1 >= imesa->i830Screen->width) x1 = imesa->i830Screen->width-1; + if (y1 >= imesa->i830Screen->height) y1 = imesa->i830Screen->height-1; + + + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); + imesa->BufferSetup[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); + imesa->BufferSetup[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); +} + +static void i830LogicOp(GLcontext *ctx, GLenum opcode) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int tmp = 0; + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + /* FIXME: This should be a look-up table, like the r200 driver. */ + switch(opcode) { + case GL_CLEAR: + tmp = LOGICOP_CLEAR; + break; + case GL_AND: + tmp = LOGICOP_AND; + break; + case GL_AND_REVERSE: + tmp = LOGICOP_AND_RVRSE; + break; + case GL_COPY: + tmp = LOGICOP_COPY; + break; + case GL_COPY_INVERTED: + tmp = LOGICOP_COPY_INV; + break; + case GL_AND_INVERTED: + tmp = LOGICOP_AND_INV; + break; + case GL_NOOP: + tmp = LOGICOP_NOOP; + break; + case GL_XOR: + tmp = LOGICOP_XOR; + break; + case GL_OR: + tmp = LOGICOP_OR; + break; + case GL_OR_INVERTED: + tmp = LOGICOP_OR_INV; + break; + case GL_NOR: + tmp = LOGICOP_NOR; + break; + case GL_EQUIV: + tmp = LOGICOP_EQUIV; + break; + case GL_INVERT: + tmp = LOGICOP_INV; + break; + case GL_OR_REVERSE: + tmp = LOGICOP_OR_RVRSE; + break; + case GL_NAND: + tmp = LOGICOP_NAND; + break; + case GL_SET: + tmp = LOGICOP_SET; + break; + default: + return; + } + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE4] &= ~LOGICOP_MASK; + imesa->Setup[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); + + /* Make sure all the enables are correct */ + i830EvalLogicOpBlendState(ctx); +} + +/* Fallback to swrast for select and feedback. + */ +static void i830RenderMode( GLcontext *ctx, GLenum mode ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + FALLBACK( imesa, I830_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); +} + +static void i830DrawBuffer(GLcontext *ctx, GLenum mode ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + /* + * _ColorDrawBufferMask is easier to cope with than <mode>. + */ + switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { + case BUFFER_BIT_FRONT_LEFT: + I830_FIREVERTICES(imesa); + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->fbOffset; + i830XMesaSetFrontClipRects( imesa ); + FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + case BUFFER_BIT_BACK_LEFT: + I830_FIREVERTICES(imesa); + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = + imesa->i830Screen->backOffset; + i830XMesaSetBackClipRects( imesa ); + FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + default: + /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ + FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + + /* We want to update the s/w rast state too so that i830SetBuffer() + * gets called. + */ + _swrast_DrawBuffer(ctx, mode); +} + +static void i830ReadBuffer(GLcontext *ctx, GLenum mode ) +{ + /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ +} + +static void i830ClearColor(GLcontext *ctx, const GLfloat color[4]) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + CLAMPED_FLOAT_TO_UBYTE(imesa->clear_red, color[0]); + CLAMPED_FLOAT_TO_UBYTE(imesa->clear_green, color[1]); + CLAMPED_FLOAT_TO_UBYTE(imesa->clear_blue, color[2]); + CLAMPED_FLOAT_TO_UBYTE(imesa->clear_alpha, color[3]); + + imesa->ClearColor = i830PackColor(imesa->i830Screen->fbFormat, + imesa->clear_red, + imesa->clear_green, + imesa->clear_blue, + imesa->clear_alpha); +} + +static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint mode = CULLMODE_BOTH; + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { + mode = CULLMODE_CW; + + if (ctx->Polygon.CullFaceMode == GL_FRONT) + mode ^= (CULLMODE_CW ^ CULLMODE_CCW); + if (ctx->Polygon.FrontFace != GL_CCW) + mode ^= (CULLMODE_CW ^ CULLMODE_CCW); + } + + imesa->LcsCullMode = mode; + + if (ctx->Polygon.CullFlag) { + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; + imesa->Setup[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode; + } +} + +static void i830LineWidth( GLcontext *ctx, GLfloat widthf ) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + int width; + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + width = FloatToInt(widthf * 2); + CLAMP_SELF(width, 1, 15); + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_LINE_WIDTH_MASK; + imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_LINE_WIDTH | + FIXED_LINE_WIDTH(width)); +} + +static void i830PointSize(GLcontext *ctx, GLfloat size) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLint point_size = FloatToInt(size); + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + CLAMP_SELF(point_size, 1, 256); + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK; + imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH | + FIXED_POINT_WIDTH(point_size)); +} + + +/* ============================================================= + * Color masks + */ + +static void i830ColorMask(GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + GLuint tmp = 0; + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a); + + imesa->mask_red = !r; + imesa->mask_green = !g; + imesa->mask_blue = !b; + imesa->mask_alpha = !a; + + tmp = (imesa->Setup[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) | + ENABLE_COLOR_MASK | + ENABLE_COLOR_WRITE | + ((!r) << WRITEMASK_RED_SHIFT) | + ((!g) << WRITEMASK_GREEN_SHIFT) | + ((!b) << WRITEMASK_BLUE_SHIFT) | + ((!a) << WRITEMASK_ALPHA_SHIFT); + + if (tmp != imesa->Setup[I830_CTXREG_ENABLES_2]) { + I830_FIREVERTICES(imesa); + imesa->dirty |= I830_UPLOAD_CTX; + imesa->Setup[I830_CTXREG_ENABLES_2] = tmp; + } +} + +static void update_specular( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; + + if (NEED_SECONDARY_COLOR(ctx)) + imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; + else + imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD; +} + +static void i830LightModelfv(GLcontext *ctx, GLenum pname, + const GLfloat *param) +{ + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + update_specular( ctx ); + } +} + +/* In Mesa 3.5 we can reliably do native flatshading. + */ +static void i830ShadeModel(GLcontext *ctx, GLenum mode) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + + +#define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4)) + + imesa->Setup[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK; + + if (mode == GL_FLAT) { + imesa->Setup[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) | + FOG_SHADE_MODE(SHADE_MODE_FLAT) | + SPEC_SHADE_MODE(SHADE_MODE_FLAT) | + COLOR_SHADE_MODE(SHADE_MODE_FLAT)); + } else { + imesa->Setup[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | + FOG_SHADE_MODE(SHADE_MODE_LINEAR) | + SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | + COLOR_SHADE_MODE(SHADE_MODE_LINEAR)); + } +} + +/* ============================================================= + * Fog + */ +static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + if (I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + if (pname == GL_FOG_COLOR) { + GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) | + ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) | + ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0)); + + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD | color); + } +} + +/* ============================================================= + */ + +static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + switch(cap) { + case GL_LIGHTING: + case GL_COLOR_SUM_EXT: + update_specular( ctx ); + break; + + case GL_ALPHA_TEST: + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK; + if (state) + imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST; + else + imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST; + + break; + + case GL_BLEND: + case GL_COLOR_LOGIC_OP: + case GL_INDEX_LOGIC_OP: + i830EvalLogicOpBlendState(ctx); + break; + + case GL_DITHER: + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER; + + if (state) + imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER; + else + imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER; + break; + + case GL_DEPTH_TEST: + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; + + if (state) + imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; + else + imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; + + /* Also turn off depth writes when GL_DEPTH_TEST is disabled: + */ + i830DepthMask( ctx, state ); + break; + + case GL_SCISSOR_TEST: + I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS); + + if (state) + imesa->BufferSetup[I830_DESTREG_SENABLE] = + (STATE3D_SCISSOR_ENABLE_CMD | + ENABLE_SCISSOR_RECT); + else + imesa->BufferSetup[I830_DESTREG_SENABLE] = + (STATE3D_SCISSOR_ENABLE_CMD | + DISABLE_SCISSOR_RECT); + + imesa->upload_cliprects = GL_TRUE; + break; + + case GL_LINE_SMOOTH: + if (imesa->reduced_primitive == GL_LINES) { + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + + imesa->Setup[I830_CTXREG_AA] &= ~AA_LINE_ENABLE; + if (state) + imesa->Setup[I830_CTXREG_AA] |= AA_LINE_ENABLE; + else + imesa->Setup[I830_CTXREG_AA] |= AA_LINE_DISABLE; + } + break; + + case GL_FOG: + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK; + if (state) + imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_ENABLE_FOG; + else + imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_DISABLE_FOG; + break; + + case GL_CULL_FACE: + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; + if (state) + imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE | + imesa->LcsCullMode); + else + imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE | + CULLMODE_NONE); + break; + + case GL_TEXTURE_2D: +/* I830_STATECHANGE(imesa, I830_UPLOAD_CTX); */ +/* imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; */ + break; + + case GL_STENCIL_TEST: + if (imesa->hw_stencil) { + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; + imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE; + + if (state) { + imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; + imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; + } else { + imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; + imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE; + } + } else { + FALLBACK( imesa, I830_FALLBACK_STENCIL, state ); + } + break; + + case GL_POLYGON_STIPPLE: +#if 0 + /* The stipple command worked on my 855GM box, but not my 845G. + * I'll do more testing later to find out exactly which hardware + * supports it. Disabled for now. + */ + if (imesa->hw_stipple && imesa->reduced_primitive == GL_TRIANGLES) + { + I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE); + imesa->StippleSetup[I830_STPREG_ST1] &= ~ST1_ENABLE; + if (state) + imesa->StippleSetup[I830_STPREG_ST1] |= ST1_ENABLE; + } +#endif + break; + + default: + ; + } +} + + +void i830EmitDrawingRectangle( i830ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + i830ScreenPrivate *i830Screen = imesa->i830Screen; + int x0 = imesa->drawX; + int y0 = imesa->drawY; + int x1 = x0 + dPriv->w; + int y1 = y0 + dPriv->h; + + /* Don't set drawing rectangle */ + if (I830_DEBUG & DEBUG_IOCTL) + fprintf(stderr, "%s x0(%d) x1(%d) y0(%d) y1(%d)\n", __FUNCTION__, + x0, x1, y0, y1); + + /* Coordinate origin of the window - may be offscreen. + */ + imesa->BufferSetup[I830_DESTREG_DR4] = ((y0<<16) | + (((unsigned)x0)&0xFFFF)); + + /* Clip to screen. + */ + if (x0 < 0) x0 = 0; + if (y0 < 0) y0 = 0; + if (x1 > i830Screen->width-1) x1 = i830Screen->width-1; + if (y1 > i830Screen->height-1) y1 = i830Screen->height-1; + + + /* Onscreen drawing rectangle. + */ + imesa->BufferSetup[I830_DESTREG_DR2] = ((y0<<16) | x0); + imesa->BufferSetup[I830_DESTREG_DR3] = (((y1+1)<<16) | (x1+1)); + + + /* Just add in our dirty flag, since we might be called when locked */ + /* Might want to modify how this is done. */ + imesa->dirty |= I830_UPLOAD_BUFFERS; + + if (0) + fprintf(stderr, "[%s] DR2(0x%08x) DR3(0x%08x) DR4(0x%08x)\n", + __FUNCTION__, + imesa->BufferSetup[I830_DESTREG_DR2], + imesa->BufferSetup[I830_DESTREG_DR3], + imesa->BufferSetup[I830_DESTREG_DR4]); +} + +/* This could be done in hardware, will do once I have the driver + * up and running. + */ +static void i830CalcViewport( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = imesa->ViewportMatrix.m; + + /* See also i830_translate_vertex. SUBPIXEL adjustments can be done + * via state vars, too. + */ + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + m[MAT_SY] = - v[MAT_SY]; + m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + SUBPIXEL_Y; + m[MAT_SZ] = v[MAT_SZ] * imesa->depth_scale; + m[MAT_TZ] = v[MAT_TZ] * imesa->depth_scale; +} + +static void i830Viewport( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + /* update size of Mesa/software ancillary buffers */ + _mesa_ResizeBuffersMESA(); + i830CalcViewport( ctx ); +} + +static void i830DepthRange( GLcontext *ctx, + GLclampd nearval, GLclampd farval ) +{ + i830CalcViewport( ctx ); +} + +void i830PrintDirty( const char *msg, GLuint state ) +{ + fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s\n", + msg, + (unsigned int) state, + (state & I830_UPLOAD_TEX0) ? "upload-tex0, " : "", + (state & I830_UPLOAD_TEX1) ? "upload-tex1, " : "", + (state & I830_UPLOAD_TEX2) ? "upload-tex2, " : "", + (state & I830_UPLOAD_TEX3) ? "upload-tex3, " : "", + (state & I830_UPLOAD_CTX) ? "upload-ctx, " : "", + (state & I830_UPLOAD_BUFFERS) ? "upload-bufs, " : "", + (state & I830_UPLOAD_TEXBLEND0) ? "upload-blend0, " : "", + (state & I830_UPLOAD_TEXBLEND1) ? "upload-blend1, " : "", + (state & I830_UPLOAD_TEXBLEND2) ? "upload-blend2, " : "", + (state & I830_UPLOAD_TEXBLEND3) ? "upload-blend3, " : "", + (state & I830_UPLOAD_STIPPLE) ? "stipple, " : "" + ); +} + +/* Push the state into the sarea and/or texture memory. + */ +void i830EmitHwStateLocked( i830ContextPtr imesa ) +{ + int i; + + if (I830_DEBUG & DEBUG_STATE) + i830PrintDirty( __FUNCTION__, imesa->dirty ); + + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if ( ((imesa->dirty & I830_UPLOAD_TEX_N_IMAGE( i )) != 0) + && (imesa->CurrentTexObj[i] != NULL) ) { + i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[i]); + } + } + + if (imesa->dirty & I830_UPLOAD_CTX) { + memcpy( imesa->sarea->ContextState, + imesa->Setup, sizeof(imesa->Setup) ); + } + + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) { + unsigned * TexState; + + imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i); + + switch( i ) { + case 0: + case 1: + TexState = imesa->sarea->TexState[i]; + break; + + case 2: + TexState = imesa->sarea->TexState2; + break; + + case 3: + TexState = imesa->sarea->TexState3; + break; + } + + memcpy(TexState, imesa->CurrentTexObj[i]->Setup, + sizeof(imesa->sarea->TexState[i])); + + TexState[I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK; + TexState[I830_TEXREG_TM0S3] |= imesa->LodBias[i]; + + /* Update the LRU usage */ + if (imesa->CurrentTexObj[i]->base.memBlock) + driUpdateTextureLRU( (driTextureObject *) + imesa->CurrentTexObj[i] ); + } + } + /* Need to figure out if texturing state, or enable changed. */ + + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) { + unsigned * TexBlendState; + unsigned * words_used; + + imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i); + + switch( i ) { + case 0: + case 1: + TexBlendState = imesa->sarea->TexBlendState[i]; + words_used = & imesa->sarea->TexBlendStateWordsUsed[i]; + break; + + case 2: + TexBlendState = imesa->sarea->TexBlendState2; + words_used = & imesa->sarea->TexBlendStateWordsUsed2; + break; + + case 3: + TexBlendState = imesa->sarea->TexBlendState3; + words_used = & imesa->sarea->TexBlendStateWordsUsed3; + break; + } + + memcpy(TexBlendState, imesa->TexBlend[i], + imesa->TexBlendWordsUsed[i] * 4); + *words_used = imesa->TexBlendWordsUsed[i]; + } + } + + if (imesa->dirty & I830_UPLOAD_BUFFERS) { + memcpy( imesa->sarea->BufferState,imesa->BufferSetup, + sizeof(imesa->BufferSetup) ); + } + + if (imesa->dirty & I830_UPLOAD_STIPPLE) { + memcpy( imesa->sarea->StippleState,imesa->StippleSetup, + sizeof(imesa->StippleSetup) ); + } + + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { + memcpy( imesa->sarea->Palette[0],imesa->palette, + sizeof(imesa->sarea->Palette[0])); + } else { + i830TextureObjectPtr p; + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { + p = imesa->CurrentTexObj[0]; + memcpy( imesa->sarea->Palette[0],p->palette, + sizeof(imesa->sarea->Palette[0])); + } + if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { + p = imesa->CurrentTexObj[1]; + memcpy( imesa->sarea->Palette[1], + p->palette, + sizeof(imesa->sarea->Palette[1])); + } + } + + imesa->sarea->dirty |= (imesa->dirty & ~(I830_UPLOAD_TEX_MASK | + I830_UPLOAD_TEXBLEND_MASK)); + + imesa->upload_cliprects = GL_TRUE; + imesa->dirty = 0; +} + + +void i830DDInitState( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + i830ScreenPrivate *i830Screen = imesa->i830Screen; + int i; + + imesa->clear_red = 0; + imesa->clear_green = 0; + imesa->clear_blue = 0; + imesa->clear_alpha = 0; + + imesa->mask_red = GL_FALSE; + imesa->mask_green = GL_FALSE; + imesa->mask_blue = GL_FALSE; + imesa->mask_alpha = GL_FALSE; + + /* Zero all texture state */ + for (i = 0; i < I830_MAX_TEXTURE_UNITS; i++) { + (void) memset( imesa->TexBlend[i], 0, sizeof( imesa->TexBlend[i] ) ); + (void) memset( imesa->Init_TexBlend[i], 0, sizeof( imesa->Init_TexBlend[i] ) ); + + imesa->TexBlendWordsUsed[i] = 0; + imesa->Init_TexBlendWordsUsed[i] = 0; + } + + /* Set default blend state */ + imesa->TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXOP_LAST_STAGE | + TEXBLENDOP_ARG1); + imesa->TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_DIFFUSE); + imesa->TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_DIFFUSE); + + imesa->TexBlendWordsUsed[0] = 4; + + imesa->Init_TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXOP_LAST_STAGE | + TEXBLENDOP_ARG1); + imesa->Init_TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->Init_TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->Init_TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->Init_TexBlendWordsUsed[0] = 4; + + memset(imesa->Setup, 0, sizeof(imesa->Setup)); + + imesa->Setup[I830_CTXREG_VF] = 0; + imesa->Setup[I830_CTXREG_VF2] = 0; + + imesa->Setup[I830_CTXREG_AA] = (STATE3D_AA_CMD | + AA_LINE_ECAAR_WIDTH_ENABLE | + AA_LINE_ECAAR_WIDTH_1_0 | + AA_LINE_REGION_WIDTH_ENABLE | + AA_LINE_REGION_WIDTH_1_0 | + AA_LINE_DISABLE); + + imesa->Setup[I830_CTXREG_ENABLES_1] = (STATE3D_ENABLES_1_CMD | + DISABLE_LOGIC_OP | + DISABLE_STENCIL_TEST | + DISABLE_DEPTH_BIAS | + DISABLE_SPEC_ADD | + I830_DISABLE_FOG | + DISABLE_ALPHA_TEST | + DISABLE_COLOR_BLEND | + DISABLE_DEPTH_TEST); + + if (imesa->hw_stencil) { + imesa->Setup[I830_CTXREG_ENABLES_2] = (STATE3D_ENABLES_2_CMD | + ENABLE_STENCIL_WRITE | + ENABLE_TEX_CACHE | + ENABLE_DITHER | + ENABLE_COLOR_MASK | + /* set no color comps disabled */ + ENABLE_COLOR_WRITE | + ENABLE_DEPTH_WRITE); + } else { + imesa->Setup[I830_CTXREG_ENABLES_2] = (STATE3D_ENABLES_2_CMD | + DISABLE_STENCIL_WRITE | + ENABLE_TEX_CACHE | + ENABLE_DITHER | + ENABLE_COLOR_MASK | + /* set no color comps disabled */ + ENABLE_COLOR_WRITE | + ENABLE_DEPTH_WRITE); + } + + imesa->Setup[I830_CTXREG_STATE1] = (STATE3D_MODES_1_CMD | + ENABLE_COLR_BLND_FUNC | + BLENDFUNC_ADD | + ENABLE_SRC_BLND_FACTOR | + SRC_BLND_FACT(BLENDFACT_ONE) | + ENABLE_DST_BLND_FACTOR | + DST_BLND_FACT(BLENDFACT_ZERO) ); + + imesa->Setup[I830_CTXREG_STATE2] = (STATE3D_MODES_2_CMD | + ENABLE_GLOBAL_DEPTH_BIAS | + GLOBAL_DEPTH_BIAS(0) | + ENABLE_ALPHA_TEST_FUNC | + ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) | + ALPHA_REF_VALUE(0) ); + + imesa->Setup[I830_CTXREG_STATE3] = (STATE3D_MODES_3_CMD | + ENABLE_DEPTH_TEST_FUNC | + DEPTH_TEST_FUNC(COMPAREFUNC_LESS) | + ENABLE_ALPHA_SHADE_MODE | + ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_FOG_SHADE_MODE | + FOG_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_SPEC_SHADE_MODE | + SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_COLOR_SHADE_MODE | + COLOR_SHADE_MODE(SHADE_MODE_LINEAR) | + ENABLE_CULL_MODE | + CULLMODE_NONE); + + imesa->Setup[I830_CTXREG_STATE4] = (STATE3D_MODES_4_CMD | + ENABLE_LOGIC_OP_FUNC | + LOGIC_OP_FUNC(LOGICOP_COPY) | + ENABLE_STENCIL_TEST_MASK | + STENCIL_TEST_MASK(0xff) | + ENABLE_STENCIL_WRITE_MASK | + STENCIL_WRITE_MASK(0xff)); + + imesa->Setup[I830_CTXREG_STENCILTST] = (STATE3D_STENCIL_TEST_CMD | + ENABLE_STENCIL_PARMS | + STENCIL_FAIL_OP(STENCILOP_KEEP) | + STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP) | + STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP) | + ENABLE_STENCIL_TEST_FUNC | + STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS) | + ENABLE_STENCIL_REF_VALUE | + STENCIL_REF_VALUE(0) ); + + imesa->Setup[I830_CTXREG_STATE5] = (STATE3D_MODES_5_CMD | + FLUSH_TEXTURE_CACHE | + ENABLE_SPRITE_POINT_TEX | + SPRITE_POINT_TEX_OFF | + ENABLE_FIXED_LINE_WIDTH | + FIXED_LINE_WIDTH(0x2) | /* 1.0 */ + ENABLE_FIXED_POINT_WIDTH | + FIXED_POINT_WIDTH(1) ); + + imesa->Setup[I830_CTXREG_IALPHAB] = (STATE3D_INDPT_ALPHA_BLEND_CMD | + DISABLE_INDPT_ALPHA_BLEND | + ENABLE_ALPHA_BLENDFUNC | + ABLENDFUNC_ADD); + + imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD | + FOG_COLOR_RED(0) | + FOG_COLOR_GREEN(0) | + FOG_COLOR_BLUE(0)); + + imesa->Setup[I830_CTXREG_BLENDCOLR0] = (STATE3D_CONST_BLEND_COLOR_CMD); + + imesa->Setup[I830_CTXREG_BLENDCOLR] = 0; + + imesa->Setup[I830_CTXREG_MCSB0] = STATE3D_MAP_COORD_SETBIND_CMD; + imesa->Setup[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) | + TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | + TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | + TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); + + imesa->LcsCullMode = CULLMODE_CW; /* GL default */ + + memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup)); + memset(imesa->StippleSetup, 0, sizeof(imesa->StippleSetup)); + + + if (imesa->glCtx->Visual.doubleBufferMode && + imesa->sarea->pf_current_page == 0) { + imesa->drawMap = i830Screen->back.map; + imesa->readMap = i830Screen->back.map; + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->backOffset; + imesa->BufferSetup[I830_DESTREG_DBUFADDR] = 0; + } else { + /* use front buffer by default */ + imesa->drawMap = (char *)imesa->driScreen->pFB; + imesa->readMap = (char *)imesa->driScreen->pFB; + imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset; + imesa->BufferSetup[I830_DESTREG_DBUFADDR] = 0; + } + + imesa->BufferSetup[I830_DESTREG_DV0] = STATE3D_DST_BUF_VARS_CMD; + + switch (i830Screen->fbFormat) { + case DV_PF_555: + case DV_PF_565: + imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + i830Screen->fbFormat | + DEPTH_IS_Z | + DEPTH_FRMT_16_FIXED); + break; + case DV_PF_8888: + imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + i830Screen->fbFormat | + DEPTH_IS_Z | + DEPTH_FRMT_24_FIXED_8_OTHER); + break; + } + imesa->BufferSetup[I830_DESTREG_SENABLE] = (STATE3D_SCISSOR_ENABLE_CMD | + DISABLE_SCISSOR_RECT); + imesa->BufferSetup[I830_DESTREG_SR0] = STATE3D_SCISSOR_RECT_0_CMD; + imesa->BufferSetup[I830_DESTREG_SR1] = 0; + imesa->BufferSetup[I830_DESTREG_SR2] = 0; + + imesa->BufferSetup[I830_DESTREG_DR0] = STATE3D_DRAW_RECT_CMD; + imesa->BufferSetup[I830_DESTREG_DR1] = 0; + imesa->BufferSetup[I830_DESTREG_DR2] = 0; + imesa->BufferSetup[I830_DESTREG_DR3] = (((i830Screen->height)<<16) | + (i830Screen->width)); + imesa->BufferSetup[I830_DESTREG_DR4] = 0; + + memcpy( imesa->Init_Setup, + imesa->Setup, + sizeof(imesa->Setup) ); + memcpy( imesa->Init_BufferSetup, + imesa->BufferSetup, + sizeof(imesa->BufferSetup) ); + +} + +static void i830InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + I830_CONTEXT(ctx)->NewGLState |= new_state; +} + +void i830DDInitStateFuncs(GLcontext *ctx) +{ + /* Callbacks for internal Mesa events. + */ + ctx->Driver.UpdateState = i830InvalidateState; + + /* API callbacks + */ + ctx->Driver.AlphaFunc = i830AlphaFunc; + ctx->Driver.BlendEquationSeparate = i830BlendEquationSeparate; + ctx->Driver.BlendFuncSeparate = i830BlendFuncSeparate; + ctx->Driver.BlendColor = i830BlendColor; + ctx->Driver.ClearColor = i830ClearColor; + ctx->Driver.ColorMask = i830ColorMask; + ctx->Driver.CullFace = i830CullFaceFrontFace; + ctx->Driver.DepthFunc = i830DepthFunc; + ctx->Driver.DepthMask = i830DepthMask; + ctx->Driver.Enable = i830Enable; + ctx->Driver.Fogfv = i830Fogfv; + ctx->Driver.FrontFace = i830CullFaceFrontFace; + ctx->Driver.LineWidth = i830LineWidth; + ctx->Driver.PointSize = i830PointSize; + ctx->Driver.LogicOpcode = i830LogicOp; + ctx->Driver.PolygonStipple = i830PolygonStippleFallback; + ctx->Driver.RenderMode = i830RenderMode; + ctx->Driver.Scissor = i830Scissor; + ctx->Driver.DrawBuffer = i830DrawBuffer; + ctx->Driver.ReadBuffer = i830ReadBuffer; + ctx->Driver.ShadeModel = i830ShadeModel; + ctx->Driver.DepthRange = i830DepthRange; + ctx->Driver.Viewport = i830Viewport; + ctx->Driver.LightModelfv = i830LightModelfv; + + ctx->Driver.StencilFunc = i830StencilFunc; + ctx->Driver.StencilMask = i830StencilMask; + ctx->Driver.StencilOp = i830StencilOp; + + /* Pixel path fallbacks. + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + + /* Swrast hooks for imaging extensions: + */ + ctx->Driver.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_state.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_state.h new file mode 100644 index 000000000..b65165124 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_state.h @@ -0,0 +1,68 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.h,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keith@tungstengraphics.com> + */ +#ifndef _I830_STATE_H +#define _I830_STATE_H + +#include "i830_context.h" +#include "colormac.h" +#define FloatToInt(F) ((int)(F)) + +/* + * * This function/macro is sensitive to precision. Test carefully + * * if you change it. + * */ +#define FLOAT_COLOR_TO_UBYTE_COLOR(b, f) \ + do { \ + union {GLfloat r; GLuint i; } tmp; \ + tmp.r = f; \ + b = ((tmp.i >= IEEE_ONE) \ + ? ((GLint)tmp.i < 0) ? (GLubyte)0 : (GLubyte)255 \ + : (tmp.r = tmp.r*(255.0F/256.0F) + 32768.0F, \ + (GLubyte)tmp.i)); \ + } while (0) + + + +extern void i830DDInitState( GLcontext *ctx ); +extern void i830DDInitStateFuncs( GLcontext *ctx ); + +extern void i830PrintDirty( const char *msg, GLuint state ); +extern void i830SetDrawBuffer(GLcontext *ctx, GLenum mode ); + +extern void i830Fallback( i830ContextPtr imesa, GLuint bit, GLboolean mode ); +#define FALLBACK( imesa, bit, mode ) i830Fallback( imesa, bit, mode ) +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tex.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tex.c new file mode 100644 index 000000000..41b5d9293 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tex.c @@ -0,0 +1,700 @@ +/************************************************************************** + +Copyright 2001 2d3d Inc., Delray Beach, FL + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tex.c,v 1.5 2003/05/07 21:56:31 dawes Exp $ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keithw@tungstengraphics.com> + */ + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "simple_list.h" +#include "enums.h" +#include "texstore.h" +#include "teximage.h" +#include "texformat.h" +#include "texmem.h" +#include "texobj.h" +#include "swrast/swrast.h" +#include "texobj.h" +#include "mm.h" + +#include "i830_screen.h" +#include "i830_dri.h" +#include "i830_context.h" +#include "i830_tex.h" +#include "i830_state.h" +#include "i830_ioctl.h" + +/* + * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias. + */ +static void i830ComputeLodBias( i830ContextPtr imesa, unsigned unit, + GLfloat bias ) +{ + int b; + + b = (int) (bias * 16.0); + if(b > 63) b = 63; + else if (b < -64) b = -64; + imesa->LodBias[ unit ] = ((b << TM0S3_LOD_BIAS_SHIFT) & + TM0S3_LOD_BIAS_MASK); +} + + +/** + * Set the texture wrap modes. + * + * The i830M (and related graphics cores) do not support GL_CLAMP. The Intel + * drivers for "other operating systems" implement GL_CLAMP as + * GL_CLAMP_TO_EDGE, so the same is done here. + * + * \param t Texture object whose wrap modes are to be set + * \param swrap Wrap mode for the \a s texture coordinate + * \param twrap Wrap mode for the \a t texture coordinate + */ + +static void i830SetTexWrapping(i830TextureObjectPtr tex, + GLenum swrap, GLenum twrap) +{ + tex->Setup[I830_TEXREG_MCS] &= ~(TEXCOORD_ADDR_U_MASK|TEXCOORD_ADDR_V_MASK); + + switch( swrap ) { + case GL_REPEAT: + tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP); + break; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP); + break; + case GL_CLAMP_TO_BORDER: + tex->Setup[I830_TEXREG_MCS] |= + TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER); + break; + case GL_MIRRORED_REPEAT: + tex->Setup[I830_TEXREG_MCS] |= + TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_MIRROR); + break; + default: + _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__); + } + + switch( twrap ) { + case GL_REPEAT: + tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP); + break; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP); + break; + case GL_CLAMP_TO_BORDER: + tex->Setup[I830_TEXREG_MCS] |= + TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER); + break; + case GL_MIRRORED_REPEAT: + tex->Setup[I830_TEXREG_MCS] |= + TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_MIRROR); + break; + default: + _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__); + } +} + +static void i830SetTexMaxAnisotropy( i830TextureObjectPtr t, GLfloat max ) +{ + t->max_anisotropy = max; +} + + +/** + * Set the texture magnification and minification modes. + * + * \param t Texture whose filter modes are to be set + * \param minf Texture minification mode + * \param magf Texture magnification mode + * \param bias LOD bias for this texture unit. + */ + +static void i830SetTexFilter( i830TextureObjectPtr t, + GLenum minf, GLenum magf ) +{ + int minFilt = 0, mipFilt = 0, magFilt = 0; + + if(I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + if ( t->max_anisotropy > 1.0 ) { + minFilt = FILTER_ANISOTROPIC; + magFilt = FILTER_ANISOTROPIC; + } + else { + switch (minf) { + case GL_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NONE; + break; + case GL_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + minFilt = FILTER_NEAREST; + mipFilt = MIPFILTER_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + minFilt = FILTER_LINEAR; + mipFilt = MIPFILTER_LINEAR; + break; + default: + _mesa_problem(NULL, "%s: Unsupported min. filter %d", __FUNCTION__, + (int) minf ); + break; + } + + switch (magf) { + case GL_NEAREST: + magFilt = FILTER_NEAREST; + break; + case GL_LINEAR: + magFilt = FILTER_LINEAR; + break; + default: + _mesa_problem(NULL, "%s: Unsupported mag. filter %d", __FUNCTION__, + (int) magf ); + break; + } + } + + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_FILTER_MASK; + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIP_FILTER_MASK; + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAG_FILTER_MASK; + t->Setup[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) | + (mipFilt << TM0S3_MIP_FILTER_SHIFT) | + (magFilt << TM0S3_MAG_FILTER_SHIFT)); +} + +static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4]) +{ + if(I830_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + t->Setup[I830_TEXREG_TM0S4] = + I830PACKCOLOR8888(color[0],color[1],color[2],color[3]); +} + + +/** + * Allocate space for and load the mesa images into the texture memory block. + * This will happen before drawing with a new texture, or drawing with a + * texture after it was swapped out or teximaged again. + */ + +static i830TextureObjectPtr i830AllocTexObj( struct gl_texture_object *texObj ) +{ + i830TextureObjectPtr t; + + t = CALLOC_STRUCT( i830_texture_object_t ); + texObj->DriverData = t; + if ( t != NULL ) { + /* Initialize non-image-dependent parts of the state: + */ + t->base.tObj = texObj; + + t->Setup[I830_TEXREG_TM0LI] = STATE3D_LOAD_STATE_IMMEDIATE_2; + t->Setup[I830_TEXREG_TM0S0] = TM0S0_USE_FENCE; + t->Setup[I830_TEXREG_TM0S1] = 0; + t->Setup[I830_TEXREG_TM0S2] = 0; + t->Setup[I830_TEXREG_TM0S3] = 0; + + t->Setup[I830_TEXREG_NOP0] = 0; + t->Setup[I830_TEXREG_NOP1] = 0; + t->Setup[I830_TEXREG_NOP2] = 0; + + t->Setup[I830_TEXREG_MCS] = (STATE3D_MAP_COORD_SET_CMD | + MAP_UNIT(0) | + ENABLE_TEXCOORD_PARAMS | + TEXCOORDS_ARE_NORMAL | + TEXCOORDTYPE_CARTESIAN | + ENABLE_ADDR_V_CNTL | + TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) | + ENABLE_ADDR_U_CNTL | + TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP)); + + make_empty_list( & t->base ); + + i830SetTexWrapping( t, texObj->WrapS, texObj->WrapT ); + i830SetTexMaxAnisotropy( t, texObj->MaxAnisotropy ); + i830SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); + i830SetTexBorderColor( t, texObj->_BorderChan ); + } + + return t; +} + + +static void i830TexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; + GLuint unit = ctx->Texture.CurrentUnit; + + if (!t) + return; + + if ( target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_NV ) + return; + + /* Can't do the update now as we don't know whether to flush + * vertices or not. Setting imesa->NewGLState means that + * i830UpdateTextureState() will be called before any triangles are + * rendered. If a statechange has occurred, it will be detected at + * that point, and buffered vertices flushed. + */ + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + i830SetTexMaxAnisotropy( t, tObj->MaxAnisotropy ); + i830SetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT ); + break; + + case GL_TEXTURE_BORDER_COLOR: + i830SetTexBorderColor( t, tObj->_BorderChan ); + break; + + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + /* The i830 and its successors can do a lot of this without + * reloading the textures. A project for someone? + */ + I830_FIREVERTICES( I830_CONTEXT(ctx) ); + driSwapOutTextureObject( (driTextureObject *) t ); + break; + + default: + return; + } + + if (t == imesa->CurrentTexObj[unit]) { + I830_STATECHANGE( imesa, I830_UPLOAD_TEX0 ); + } +} + + +static void i830TexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + GLuint unit = ctx->Texture.CurrentUnit; + + /* Only one env color. Need a fallback if env colors are different + * and texture setup references env color in both units. + */ + switch (pname) { + case GL_TEXTURE_ENV_COLOR: + case GL_TEXTURE_ENV_MODE: + case GL_COMBINE_RGB_EXT: + case GL_COMBINE_ALPHA_EXT: + case GL_SOURCE0_RGB_EXT: + case GL_SOURCE1_RGB_EXT: + case GL_SOURCE2_RGB_EXT: + case GL_SOURCE0_ALPHA_EXT: + case GL_SOURCE1_ALPHA_EXT: + case GL_SOURCE2_ALPHA_EXT: + case GL_OPERAND0_RGB_EXT: + case GL_OPERAND1_RGB_EXT: + case GL_OPERAND2_RGB_EXT: + case GL_OPERAND0_ALPHA_EXT: + case GL_OPERAND1_ALPHA_EXT: + case GL_OPERAND2_ALPHA_EXT: + case GL_RGB_SCALE_EXT: + case GL_ALPHA_SCALE: + imesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */ + break; + + case GL_TEXTURE_LOD_BIAS_EXT: + i830ComputeLodBias( imesa, unit, *param ); + I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) ); + break; + + default: + break; + } +} + +static void i830TexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + if (t) { + I830_FIREVERTICES( I830_CONTEXT(ctx) ); + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) i830AllocTexObj( texObj ); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + + _mesa_store_teximage2d( ctx, target, level, internalFormat, + width, height, border, format, type, + pixels, packing, texObj, texImage ); +} + +static void i830TexSubImage2D( GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + if (t) { + I830_FIREVERTICES( I830_CONTEXT(ctx) ); + driSwapOutTextureObject( t ); + } + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, + height, format, type, pixels, packing, texObj, + texImage); + +} + + + +static void i830CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + GLuint face; + + /* which cube face or ordinary 2D image */ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + ASSERT(face < 6); + break; + default: + face = 0; + } + + if ( t != NULL ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) i830AllocTexObj( texObj ); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; + } + } + + texImage->IsClientData = GL_FALSE; + + if (I830_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__); + + _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width, + height, border, imageSize, data, texObj, texImage); + + t->dirty_images[face] |= (1 << level); +} + + +static void i830CompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + GLuint face; + + + /* which cube face or ordinary 2D image */ + switch (target) { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; + ASSERT(face < 6); + break; + default: + face = 0; + } + + assert( t ); /* this _should_ be true */ + if ( t ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) i830AllocTexObj( texObj ); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D"); + return; + } + } + + _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width, + height, format, imageSize, data, texObj, texImage); + + t->dirty_images[face] |= (1 << level); +} + + +static void i830BindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) +{ + assert( (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_NV) || + (tObj->DriverData != NULL) ); +} + + +static void i830DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) +{ + driTextureObject * t = (driTextureObject *) tObj->DriverData; + if ( t != NULL ) { + i830ContextPtr imesa = I830_CONTEXT( ctx ); + + if ( imesa ) { + I830_FIREVERTICES( imesa ); + } + + driDestroyTextureObject( t ); + } + /* Free mipmap images and the texture object itself */ + _mesa_delete_texture_object(ctx, tObj); +} + + +static const struct gl_texture_format * +i830ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + const GLboolean do32bpt = ( imesa->i830Screen->cpp == 4 && + imesa->i830Screen->textureSize > 4*1024*1024); + + switch ( internalFormat ) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + if ( format == GL_BGRA ) { + if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) { + return &_mesa_texformat_argb8888; + } + else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { + return &_mesa_texformat_argb4444; + } + else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { + return &_mesa_texformat_argb1555; + } + } + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) { + return &_mesa_texformat_rgb565; + } + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; + + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; + + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + return &_mesa_texformat_rgb565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: + return &_mesa_texformat_al88; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: + return &_mesa_texformat_l8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + return &_mesa_texformat_al88; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + return &_mesa_texformat_i8; + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_MESA || + type == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; + + case GL_COMPRESSED_RGB_FXT1_3DFX: + return &_mesa_texformat_rgb_fxt1; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return &_mesa_texformat_rgba_fxt1; + + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return &_mesa_texformat_rgb_dxt1; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return &_mesa_texformat_rgba_dxt3; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + + default: + fprintf(stderr, "unexpected texture format in %s\n", __FUNCTION__); + return NULL; + } + + return NULL; /* never get here */ +} + +/** + * Allocate a new texture object. + * Called via ctx->Driver.NewTextureObject. + * Note: this function will be called during context creation to + * allocate the default texture objects. + * Note: we could use containment here to 'derive' the driver-specific + * texture object from the core mesa gl_texture_object. Not done at this time. + */ +static struct gl_texture_object * +i830NewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) +{ + struct gl_texture_object *obj; + obj = _mesa_new_texture_object(ctx, name, target); + i830AllocTexObj( obj ); + return obj; +} + +void i830InitTextureFuncs( struct dd_function_table *functions ) +{ + functions->NewTextureObject = i830NewTextureObject; + functions->DeleteTexture = i830DeleteTexture; + functions->ChooseTextureFormat = i830ChooseTextureFormat; + functions->TexImage2D = i830TexImage2D; + functions->TexSubImage2D = i830TexSubImage2D; + functions->BindTexture = i830BindTexture; + functions->TexParameter = i830TexParameter; + functions->TexEnv = i830TexEnv; + functions->IsTextureResident = driIsTextureResident; + functions->CompressedTexImage2D = i830CompressedTexImage2D; + functions->CompressedTexSubImage2D = i830CompressedTexSubImage2D; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tex.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tex.h new file mode 100644 index 000000000..68c18b105 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tex.h @@ -0,0 +1,70 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Adapted for use in the I830M driver: + * Jeff Hartmann <jhartmann@2d3d.com> + */ + +#ifndef I830TEX_INC +#define I830TEX_INC + +#include "mtypes.h" +#include "i830_context.h" +#include "i830_3d_reg.h" +#include "texmem.h" + +#define I830_TEX_MAXLEVELS 10 + +struct i830_texture_object_t +{ + driTextureObject base; + + int texelBytes; + int Pitch; + int Height; + char *BufAddr; + GLenum palette_format; + GLuint palette[256]; + struct { + const struct gl_texture_image *image; + int offset; /* into BufAddr */ + int height; + int internalFormat; + } image[6][I830_TEX_MAXLEVELS]; + + /* Support for multitexture. + */ + + GLuint current_unit; + GLuint Setup[I830_TEX_SETUP_SIZE]; + GLuint dirty; + + GLfloat max_anisotropy; +}; + +void i830UpdateTextureState( GLcontext *ctx ); +void i830InitTextureFuncs( struct dd_function_table *functions ); + +void i830DestroyTexObj( i830ContextPtr imesa, i830TextureObjectPtr t ); +int i830UploadTexImagesLocked( i830ContextPtr imesa, i830TextureObjectPtr t ); + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_texmem.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_texmem.c new file mode 100644 index 000000000..7faf90874 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_texmem.c @@ -0,0 +1,237 @@ +/************************************************************************** + +Copyright 2001 2d3d Inc., Delray Beach, FL + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_texmem.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ + +/* + * Author: + * Jeff Hartmann <jhartmann@2d3d.com> + * + * Heavily based on the I810 driver, which was written by: + * Keith Whitwell <keithw@tungstengraphics.com> + */ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "texformat.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_tex.h" +#include "i830_state.h" +#include "i830_ioctl.h" + + +void i830DestroyTexObj(i830ContextPtr imesa, i830TextureObjectPtr t) +{ + unsigned i; + + + /* See if it was the driver's current object. + */ + if ( imesa != NULL ) { + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if ( t == imesa->CurrentTexObj[ i ] ) { + imesa->CurrentTexObj[ i ] = NULL; + imesa->dirty &= ~I830_UPLOAD_TEX_N( i ); + } + } + } +} + +#if defined(i386) || defined(__i386__) +/* From linux kernel i386 header files, copes with odd sizes better + * than COPY_DWORDS would: + */ +static __inline__ void * __memcpy(void * to, const void * from, size_t n) +{ +int d0, d1, d2; +__asm__ __volatile__( + "rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); +return (to); +} +#else +/* Allow compilation on other architectures */ +#define __memcpy memcpy +#endif + +/* Upload an image from mesa's internal copy. + */ +static void i830UploadTexLevel( i830ContextPtr imesa, + i830TextureObjectPtr t, int hwlevel ) +{ + const struct gl_texture_image *image = t->image[0][hwlevel].image; + int j; + + if (!image || !image->Data) + return; + + if (image->IsCompressed) { + GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[0][hwlevel].offset); + GLubyte *src = (GLubyte *)image->Data; + + if ((t->Setup[I830_TEXREG_TM0S1] & TM0S1_MT_FORMAT_MASK)==MT_COMPRESS_FXT1) + { + for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) { + __memcpy(dst, src, (image->Width*2) ); + src += image->Width*2; + } + } + else if ((t->Setup[I830_TEXREG_TM0S1] & TM0S1_MT_FORMAT_MASK)==MT_COMPRESS_DXT1) + { + for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) { + __memcpy(dst, src, (image->Width*2) ); + src += image->Width*2; + } + } + else if (((t->Setup[I830_TEXREG_TM0S1] & TM0S1_MT_FORMAT_MASK)==MT_COMPRESS_DXT2_3) || ((t->Setup[I830_TEXREG_TM0S1] & TM0S1_MT_FORMAT_MASK)==MT_COMPRESS_DXT4_5)) + { + for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) { + __memcpy(dst, src, (image->Width*4) ); + src += image->Width*4; + } + } + } + else if (image->Width * image->TexFormat->TexelBytes == t->Pitch) { + GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[0][hwlevel].offset); + GLubyte *src = (GLubyte *)image->Data; + + memcpy( dst, src, t->Pitch * image->Height ); + } + else switch (image->TexFormat->TexelBytes) { + case 1: + { + GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[0][hwlevel].offset); + GLubyte *src = (GLubyte *)image->Data; + + for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) { + __memcpy(dst, src, image->Width ); + src += image->Width; + } + } + break; + + case 2: + { + GLushort *dst = (GLushort *)(t->BufAddr + t->image[0][hwlevel].offset); + GLushort *src = (GLushort *)image->Data; + + for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { + __memcpy(dst, src, image->Width * 2 ); + src += image->Width; + } + } + break; + + case 4: + { + GLuint *dst = (GLuint *)(t->BufAddr + t->image[0][hwlevel].offset); + GLuint *src = (GLuint *)image->Data; + + for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/4)) { + __memcpy(dst, src, image->Width * 4 ); + src += image->Width; + } + } + break; + + default: + fprintf(stderr, "%s: Not supported texel size %d\n", + __FUNCTION__, image->TexFormat->TexelBytes); + } +} + + +/* This is called with the lock held. May have to eject our own and/or + * other client's texture objects to make room for the upload. + */ + +int i830UploadTexImagesLocked( i830ContextPtr imesa, i830TextureObjectPtr t ) +{ + int ofs; + int i; + + if ( t->base.memBlock == NULL ) { + int heap; + + heap = driAllocateTexture( imesa->texture_heaps, imesa->nr_heaps, + (driTextureObject *) t ); + if ( heap == -1 ) { + return -1; + } + + /* Set the base offset of the texture image */ + ofs = t->base.memBlock->ofs; + t->BufAddr = imesa->i830Screen->tex.map + ofs; + t->Setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | + (imesa->i830Screen->textureOffset + ofs)); + + for ( i = 0 ; i < imesa->glCtx->Const.MaxTextureUnits ; i++ ) { + if (t == imesa->CurrentTexObj[i]) { + imesa->dirty |= I830_UPLOAD_TEX_N( i ); + } + } + } + + + /* Let the world know we've used this memory recently. + */ + driUpdateTextureLRU( (driTextureObject *) t ); + + if (imesa->texture_heaps[0]->timestamp >= GET_DISPATCH_AGE(imesa)) + i830WaitAgeLocked( imesa, imesa->texture_heaps[0]->timestamp ); + + /* Upload any images that are new */ + if (t->base.dirty_images[0]) { + const int numLevels = t->base.lastLevel - t->base.firstLevel + 1; + + for (i = 0 ; i < numLevels ; i++) { + if ( (t->base.dirty_images[0] & (1 << (i+t->base.firstLevel))) != 0 ) { + i830UploadTexLevel( imesa, t, i ); + } + } + t->base.dirty_images[0] = 0; + imesa->sarea->perf_boxes |= I830_BOX_TEXTURE_LOAD; + } + + return 0; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_texstate.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_texstate.c new file mode 100644 index 000000000..358c554f3 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_texstate.c @@ -0,0 +1,716 @@ +/************************************************************************** + +Copyright 2001 2d3d Inc., Delray Beach, FL + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_texstate.c,v 1.3 2002/12/10 01:26:53 dawes Exp $ */ + +/** + * \file i830_texstate.c + * + * Heavily based on the I810 driver, which was written by Keith Whitwell. + * + * \author Jeff Hartmann <jhartmann@2d3d.com> + * \author Keith Whitwell <keithw@tungstengraphics.com> + */ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "texformat.h" +#include "texstore.h" + +#include "mm.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_context.h" +#include "i830_tex.h" +#include "i830_state.h" +#include "i830_ioctl.h" + +#define I830_TEX_UNIT_ENABLED(unit) (1<<unit) + +static void i830SetTexImages( i830ContextPtr imesa, + struct gl_texture_object *tObj ) +{ + GLuint total_height, pitch, i, textureFormat; + i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; + const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; + GLint numLevels; + + switch( baseImage->TexFormat->MesaFormat ) { + case MESA_FORMAT_L8: + t->texelBytes = 1; + textureFormat = MAPSURF_8BIT | MT_8BIT_L8; + break; + + case MESA_FORMAT_I8: + t->texelBytes = 1; + textureFormat = MAPSURF_8BIT | MT_8BIT_I8; + break; + + case MESA_FORMAT_AL88: + t->texelBytes = 2; + textureFormat = MAPSURF_16BIT | MT_16BIT_AY88; + break; + + case MESA_FORMAT_RGB565: + t->texelBytes = 2; + textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; + break; + + case MESA_FORMAT_ARGB1555: + t->texelBytes = 2; + textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; + break; + + case MESA_FORMAT_ARGB4444: + t->texelBytes = 2; + textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444; + break; + + case MESA_FORMAT_ARGB8888: + t->texelBytes = 4; + textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; + break; + + case MESA_FORMAT_YCBCR_REV: + t->texelBytes = 2; + textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL | + TM0S1_COLORSPACE_CONVERSION); + break; + + case MESA_FORMAT_YCBCR: + t->texelBytes = 2; + textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY | /* ??? */ + TM0S1_COLORSPACE_CONVERSION); + break; + + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + t->texelBytes = 2; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); + break; + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGB_DXT1: + /* + * DXTn pitches are Width/4 * blocksize in bytes + * for DXT1: blocksize=8 so Width/4*8 = Width * 2 + * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4 + */ + t->texelBytes = 2; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); + break; + case MESA_FORMAT_RGBA_DXT3: + t->texelBytes = 4; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); + break; + case MESA_FORMAT_RGBA_DXT5: + t->texelBytes = 4; + textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); + break; + default: + fprintf(stderr, "%s: bad image format\n", __FUNCTION__); + free( t ); + return; + } + + /* Compute which mipmap levels we really want to send to the hardware. + */ + + driCalculateTextureFirstLastLevel( (driTextureObject *) t ); + + + /* Figure out the amount of memory required to hold all the mipmap + * levels. Choose the smallest pitch to accomodate the largest + * mipmap: + */ + numLevels = t->base.lastLevel - t->base.firstLevel + 1; + + /* Pitch would be subject to additional rules if texture memory were + * tiled. Currently it isn't. + */ + if (0) { + pitch = 128; + while (pitch < tObj->Image[0][t->base.firstLevel]->Width * t->texelBytes) + pitch *= 2; + } + else { + pitch = tObj->Image[0][t->base.firstLevel]->Width * t->texelBytes; + pitch = (pitch + 3) & ~3; + } + + + /* All images must be loaded at this pitch. Count the number of + * lines required: + */ + for ( total_height = i = 0 ; i < numLevels ; i++ ) { + t->image[0][i].image = tObj->Image[0][t->base.firstLevel + i]; + if (!t->image[0][i].image) + break; + + t->image[0][i].offset = total_height * pitch; + if (t->image[0][i].image->IsCompressed) + { + if (t->image[0][i].image->Height > 4) + total_height += t->image[0][i].image->Height/4; + else + total_height += 1; + } + else + total_height += t->image[0][i].image->Height; + t->image[0][i].internalFormat = baseImage->Format; + } + + t->Pitch = pitch; + t->base.totalSize = total_height*pitch; + t->Setup[I830_TEXREG_TM0S1] = + (((tObj->Image[0][t->base.firstLevel]->Height - 1) << TM0S1_HEIGHT_SHIFT) | + ((tObj->Image[0][t->base.firstLevel]->Width - 1) << TM0S1_WIDTH_SHIFT) | + textureFormat); + t->Setup[I830_TEXREG_TM0S2] = + ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT)); + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; + t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; + t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; + t->dirty = I830_UPLOAD_TEX0 | I830_UPLOAD_TEX1 + | I830_UPLOAD_TEX2 | I830_UPLOAD_TEX3; + + LOCK_HARDWARE( imesa ); + i830UploadTexImagesLocked( imesa, t ); + UNLOCK_HARDWARE( imesa ); +} + +/* ================================================================ + * Texture combine functions + */ + + +/** + * Calculate the hardware instuctions to setup the current texture enviromnemt + * settings. Since \c gl_texture_unit::_CurrentCombine is used, both + * "classic" texture enviroments and GL_ARB_texture_env_combine type texture + * environments are treated identically. + * + * \todo + * This function should return \c GLboolean. When \c GL_FALSE is returned, + * it means that an environment is selected that the hardware cannot do. This + * is the way the Radeon and R200 drivers work. + * + * \todo + * Looking at i830_3d_regs.h, it seems the i830 can do part of + * GL_ATI_texture_env_combine3. It can handle using \c GL_ONE and + * \c GL_ZERO as combine inputs (which the code already supports). It can + * also handle the \c GL_MODULATE_ADD_ATI mode. Is it worth investigating + * partial support for the extension? + * + * \todo + * Some thought needs to be put into the way combiners work. The driver + * treats the hardware as if there's a specific combine unit tied to each + * texture unit. That's why there's the special case for a disabled texture + * unit. That's not the way the hardware works. In reality, there are 4 + * texture units and four general instruction slots. Each instruction slot + * can use any texture as an input. There's no need for this wierd "no-op" + * stuff. If texture units 0 and 3 are enabled, the instructions to combine + * them should be in slots 0 and 1, not 0 and 3 with two no-ops inbetween. + */ + +static void i830UpdateTexEnv( GLcontext *ctx, GLuint unit ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB; + const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA; + + GLboolean need_constant_color = GL_FALSE; + GLuint blendop; + GLuint ablendop; + GLuint args_RGB[3]; + GLuint args_A[3]; + GLuint rgb_shift = texUnit->Combine.ScaleShiftRGB; + GLuint alpha_shift = texUnit->Combine.ScaleShiftA; + int i; + unsigned used; + static const GLuint tex_blend_rgb[3] = { + TEXPIPE_COLOR | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_COLOR | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_COLOR | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, + }; + static const GLuint tex_blend_a[3] = { + TEXPIPE_ALPHA | TEXBLEND_ARG1 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_ALPHA | TEXBLEND_ARG2 | TEXBLENDARG_MODIFY_PARMS, + TEXPIPE_ALPHA | TEXBLEND_ARG0 | TEXBLENDARG_MODIFY_PARMS, + }; + static const GLuint op_rgb[4] = { + 0, + TEXBLENDARG_INV_ARG, + TEXBLENDARG_REPLICATE_ALPHA, + TEXBLENDARG_REPLICATE_ALPHA | TEXBLENDARG_INV_ARG, + }; + + + + imesa->TexBlendWordsUsed[unit] = 0; + + if(I830_DEBUG&DEBUG_TEXTURE) + fprintf(stderr, "[%s:%u] env. mode = %s\n", __FUNCTION__, __LINE__, + _mesa_lookup_enum_by_nr(texUnit->EnvMode)); + + + if ( !texUnit->_ReallyEnabled ) { + imesa->TexBlend[unit][0] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[unit][1] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_SCALE_1X | + TEXOP_MODIFY_PARMS | + TEXBLENDOP_ARG1); + imesa->TexBlend[unit][2] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_COLOR | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlend[unit][3] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + TEXPIPE_ALPHA | + TEXBLEND_ARG1 | + TEXBLENDARG_MODIFY_PARMS | + TEXBLENDARG_CURRENT); + imesa->TexBlendWordsUsed[unit] = 4; + } + else { + switch(texUnit->_CurrentCombine->ModeRGB) { + case GL_REPLACE: + blendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + blendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + blendop = TEXBLENDOP_ADD; + break; + case GL_ADD_SIGNED: + blendop = TEXBLENDOP_ADDSIGNED; + break; + case GL_INTERPOLATE: + blendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT: + blendop = TEXBLENDOP_SUBTRACT; + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + /* The EXT version of the DOT3 extension does not support the + * scale factor, but the ARB version (and the version in OpenGL + * 1.3) does. + */ + rgb_shift = 0; + alpha_shift = 0; + /* FALLTHROUGH */ + + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + blendop = TEXBLENDOP_DOT3; + break; + default: + return; + } + + blendop |= (rgb_shift << TEXOP_SCALE_SHIFT); + + switch(texUnit->_CurrentCombine->ModeA) { + case GL_REPLACE: + ablendop = TEXBLENDOP_ARG1; + break; + case GL_MODULATE: + ablendop = TEXBLENDOP_MODULATE; + break; + case GL_ADD: + ablendop = TEXBLENDOP_ADD; + break; + case GL_ADD_SIGNED: + ablendop = TEXBLENDOP_ADDSIGNED; + break; + case GL_INTERPOLATE: + ablendop = TEXBLENDOP_BLEND; + break; + case GL_SUBTRACT: + ablendop = TEXBLENDOP_SUBTRACT; + break; + default: + return; + } + + if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT) + || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) { + ablendop = TEXBLENDOP_DOT3; + } + + ablendop |= (alpha_shift << TEXOP_SCALE_SHIFT); + + /* Handle RGB args */ + for( i = 0 ; i < numColorArgs ; i++ ) { + const int op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; + + assert( (op >= 0) && (op <= 3) ); + switch(texUnit->_CurrentCombine->SourceRGB[i]) { + case GL_TEXTURE: + args_RGB[i] = TEXBLENDARG_TEXEL0 + unit; + break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: + case GL_TEXTURE3: + args_RGB[i] = TEXBLENDARG_TEXEL0 + + (texUnit->_CurrentCombine->SourceRGB[i] & 0x03); + break; + case GL_CONSTANT: + args_RGB[i] = TEXBLENDARG_FACTOR_N; + need_constant_color = GL_TRUE; + break; + case GL_PRIMARY_COLOR: + args_RGB[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_RGB[i] = TEXBLENDARG_CURRENT; + break; + case GL_ONE: + args_RGB[i] = TEXBLENDARG_ONE; + break; + case GL_ZERO: + args_RGB[i] = TEXBLENDARG_ONE | TEXBLENDARG_INV_ARG; + break; + default: + return; + } + + /* Xor is used so that GL_ONE_MINUS_SRC_COLOR with GL_ZERO + * works correctly. + */ + args_RGB[i] ^= op_rgb[op]; + } + + /* Handle A args */ + for( i = 0 ; i < numAlphaArgs ; i++ ) { + const int op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; + + assert( (op >= 0) && (op <= 1) ); + switch(texUnit->_CurrentCombine->SourceA[i]) { + case GL_TEXTURE: + args_A[i] = TEXBLENDARG_TEXEL0 + unit; + break; + case GL_TEXTURE0: + case GL_TEXTURE1: + case GL_TEXTURE2: + case GL_TEXTURE3: + args_A[i] = TEXBLENDARG_TEXEL0 + + (texUnit->_CurrentCombine->SourceA[i] & 0x03); + break; + case GL_CONSTANT: + args_A[i] = TEXBLENDARG_FACTOR_N; + need_constant_color = GL_TRUE; + break; + case GL_PRIMARY_COLOR: + args_A[i] = TEXBLENDARG_DIFFUSE; + break; + case GL_PREVIOUS: + args_A[i] = TEXBLENDARG_CURRENT; + break; + case GL_ONE: + args_A[i] = TEXBLENDARG_ONE; + break; + case GL_ZERO: + args_A[i] = TEXBLENDARG_ONE | TEXBLENDARG_INV_ARG; + break; + default: + return; + } + + /* We cheat. :) The register values for this are the same as for + * RGB. Xor is used so that GL_ONE_MINUS_SRC_ALPHA with GL_ZERO + * works correctly. + */ + args_A[i] ^= op_rgb[op]; + } + + /* Native Arg1 == Arg0 in GL_EXT_texture_env_combine spec */ + /* Native Arg2 == Arg1 in GL_EXT_texture_env_combine spec */ + /* Native Arg0 == Arg2 in GL_EXT_texture_env_combine spec */ + + /* Build color pipeline */ + + used = 0; + imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_COLOR | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + DISABLE_TEX_CNTRL_STAGE | + TEXOP_MODIFY_PARMS | + blendop); + + imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_OP_CMD(unit) | + TEXPIPE_ALPHA | + ENABLE_TEXOUTPUT_WRT_SEL | + TEXOP_OUTPUT_CURRENT | + TEXOP_MODIFY_PARMS | + ablendop); + + for ( i = 0 ; i < numColorArgs ; i++ ) { + imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + tex_blend_rgb[i] | + args_RGB[i]); + } + + for ( i = 0 ; i < numAlphaArgs ; i++ ) { + imesa->TexBlend[unit][used++] = (STATE3D_MAP_BLEND_ARG_CMD(unit) | + tex_blend_a[i] | + args_A[i]); + } + + + if ( need_constant_color ) { + GLubyte r, g, b, a; + const GLfloat * const fc = texUnit->EnvColor; + + FLOAT_COLOR_TO_UBYTE_COLOR(r, fc[RCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(g, fc[GCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(b, fc[BCOMP]); + FLOAT_COLOR_TO_UBYTE_COLOR(a, fc[ACOMP]); + + imesa->TexBlend[unit][used++] = STATE3D_COLOR_FACTOR_CMD(unit); + imesa->TexBlend[unit][used++] = ((a << 24) | (r << 16) | (g << 8) | b); + } + + imesa->TexBlendWordsUsed[unit] = used; + } + + I830_STATECHANGE( imesa, I830_UPLOAD_TEXBLEND_N(unit) ); +} + + +/* This is bogus -- can't load the same texture object on two units. + */ +static void i830TexSetUnit( i830TextureObjectPtr t, GLuint unit ) +{ + if(I830_DEBUG&DEBUG_TEXTURE) + fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit); + + t->Setup[I830_TEXREG_TM0LI] = (STATE3D_LOAD_STATE_IMMEDIATE_2 | + (LOAD_TEXTURE_MAP0 << unit) | 4); + + I830_SET_FIELD(t->Setup[I830_TEXREG_MCS], MAP_UNIT_MASK, MAP_UNIT(unit)); + + t->current_unit = unit; + t->base.bound |= (1U << unit); +} + +#define TEXCOORDTYPE_MASK (~((1<<13)|(1<<12)|(1<<11))) + + +static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; + + /* Fallback if there's a texture border */ + if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) { + return GL_FALSE; + } + + /* Upload teximages (not pipelined) + */ + if (t->base.dirty_images[0]) { + i830SetTexImages( imesa, tObj ); + if (!t->base.memBlock) { + return GL_FALSE; + } + } + + /* Update state if this is a different texture object to last + * time. + */ + if (imesa->CurrentTexObj[unit] != t) { + + if ( imesa->CurrentTexObj[unit] != NULL ) { + /* The old texture is no longer bound to this texture unit. + * Mark it as such. + */ + + imesa->CurrentTexObj[unit]->base.bound &= ~(1U << unit); + } + + I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) ); + imesa->CurrentTexObj[unit] = t; + i830TexSetUnit(t, unit); + } + + /* Update texture environment if texture object image format or + * texture environment state has changed. + * + * KW: doesn't work -- change from tex0 only to tex0+tex1 gets + * missed (need to update last stage flag?). Call + * i830UpdateTexEnv always. + */ + if (tObj->Image[0][tObj->BaseLevel]->Format != + imesa->TexEnvImageFmt[unit]) { + imesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->Format; + } + i830UpdateTexEnv( ctx, unit ); + imesa->TexEnabledMask |= I830_TEX_UNIT_ENABLED(unit); + + return GL_TRUE; +} + +static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; + GLuint mcs = t->Setup[I830_TEXREG_MCS]; + + mcs &= ~TEXCOORDS_ARE_NORMAL; + mcs |= TEXCOORDS_ARE_IN_TEXELUNITS; + + if (mcs != t->Setup[I830_TEXREG_MCS]) { + I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) ); + t->Setup[I830_TEXREG_MCS] = mcs; + } + + return GL_TRUE; +} + + +static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; + GLuint mcs = t->Setup[I830_TEXREG_MCS]; + + mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS; + mcs |= TEXCOORDS_ARE_NORMAL; + + if (mcs != t->Setup[I830_TEXREG_MCS]) { + I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) ); + t->Setup[I830_TEXREG_MCS] = mcs; + } + + return GL_TRUE; +} + + +static GLboolean disable_tex( GLcontext *ctx, int unit ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + /* This is happening too often. I need to conditionally send diffuse + * state to the card. Perhaps a diffuse dirty flag of some kind. + * Will need to change this logic if more than 2 texture units are + * used. We need to only do this up to the last unit enabled, or unit + * one if nothing is enabled. + */ + + if ( imesa->CurrentTexObj[unit] != NULL ) { + /* The old texture is no longer bound to this texture unit. + * Mark it as such. + */ + + imesa->CurrentTexObj[unit]->base.bound &= ~(1U << unit); + imesa->CurrentTexObj[unit] = NULL; + } + + imesa->TexEnvImageFmt[unit] = 0; + imesa->dirty &= ~(I830_UPLOAD_TEX_N(unit)); + + i830UpdateTexEnv( ctx, unit ); + + return GL_TRUE; +} + +static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + + imesa->TexEnabledMask &= ~(I830_TEX_UNIT_ENABLED(unit)); + + if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT) { + return (enable_tex_common( ctx, unit ) && + enable_tex_2d( ctx, unit )); + } + else if (texUnit->_ReallyEnabled == TEXTURE_RECT_BIT) { + return (enable_tex_common( ctx, unit ) && + enable_tex_rect( ctx, unit )); + } + else if (texUnit->_ReallyEnabled) { + return GL_FALSE; + } + else { + return disable_tex( ctx, unit ); + } +} + + + +void i830UpdateTextureState( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int i; + int last_stage = 0; + GLboolean ok; + + for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { + if ( (ctx->Texture.Unit[i]._ReallyEnabled == TEXTURE_2D_BIT) + || (ctx->Texture.Unit[i]._ReallyEnabled == TEXTURE_RECT_BIT) ) { + last_stage = i; + } + } + + ok = GL_TRUE; + for ( i = 0 ; i <= last_stage ; i++ ) { + ok = ok && i830UpdateTexUnit( ctx, i ); + } + + FALLBACK( imesa, I830_FALLBACK_TEXTURE, !ok ); + + + /* Make sure last stage is set correctly */ + imesa->TexBlend[last_stage][0] |= TEXOP_LAST_STAGE; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tris.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tris.c new file mode 100644 index 000000000..e0907202d --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tris.c @@ -0,0 +1,1056 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tris.c,v 1.4 2002/12/10 01:26:54 dawes Exp $ */ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Original Authors: + * Keith Whitwell <keith@tungstengraphics.com> + * Adapted for use on the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> + */ + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "i830_screen.h" +#include "i830_dri.h" + +#include "i830_tris.h" +#include "i830_state.h" +#include "i830_ioctl.h" +#include "i830_span.h" + +static void i830RenderPrimitive( GLcontext *ctx, GLenum prim ); + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#if defined(USE_X86_ASM) +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (j), "=D" (vb), "=S" (__tmp) \ + : "0" (vertsize), \ + "D" ((long)vb), \ + "S" ((long)v) ); \ +} while (0) +#else +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + for ( j = 0 ; j < vertsize ; j++ ) \ + vb[j] = ((GLuint *)v)[j]; \ + vb += vertsize; \ +} while (0) +#endif + +static void __inline__ i830_draw_triangle( i830ContextPtr imesa, + i830VertexPtr v0, + i830VertexPtr v1, + i830VertexPtr v2 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i830AllocDmaLow( imesa, 3 * 4 * vertsize ); + int j; + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v2 ); +} + + +static void __inline__ i830_draw_quad( i830ContextPtr imesa, + i830VertexPtr v0, + i830VertexPtr v1, + i830VertexPtr v2, + i830VertexPtr v3 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i830AllocDmaLow( imesa, 6 * 4 * vertsize ); + int j; + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v3 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v2 ); + COPY_DWORDS( j, vb, vertsize, v3 ); +} + + +static __inline__ void i830_draw_point( i830ContextPtr imesa, + i830VertexPtr tmp ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i830AllocDmaLow( imesa, 4 * vertsize ); + int j; + + /* Adjust for sub pixel position */ + *(float *)&vb[0] = tmp->v.x - 0.125; + *(float *)&vb[1] = tmp->v.y - 0.125; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; +} + + +static __inline__ void i830_draw_line( i830ContextPtr imesa, + i830VertexPtr v0, + i830VertexPtr v1 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i830AllocDmaLow( imesa, 2 * 4 * vertsize ); + int j; + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); +} + + + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + imesa->draw_tri( imesa, a, b, c ); \ + else \ + i830_draw_triangle( imesa, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + imesa->draw_tri( imesa, a, b, d ); \ + imesa->draw_tri( imesa, b, c, d ); \ + } else \ + i830_draw_quad( imesa, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + imesa->draw_line( imesa, v0, v1 ); \ + else \ + i830_draw_line( imesa, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + imesa->draw_point( imesa, v0 ); \ + else \ + i830_draw_point( imesa, v0 ); \ +} while (0) + + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define I830_OFFSET_BIT 0x01 +#define I830_TWOSIDE_BIT 0x02 +#define I830_UNFILLED_BIT 0x04 +#define I830_FALLBACK_BIT 0x08 +#define I830_MAX_TRIFUNC 0x10 + + +static struct { + tnl_points_func points; + tnl_line_func line; + tnl_triangle_func triangle; + tnl_quad_func quad; +} rast_tab[I830_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & I830_FALLBACK_BIT) +#define DO_OFFSET (IND & I830_OFFSET_BIT) +#define DO_UNFILLED (IND & I830_UNFILLED_BIT) +#define DO_TWOSIDE (IND & I830_TWOSIDE_BIT) +#define DO_FLAT 0 +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 1 +#define HAVE_BACK_COLORS 0 +#define HAVE_HW_FLATSHADE 1 +#define VERTEX i830Vertex +#define TAB rast_tab + +#define DEPTH_SCALE (imesa->depth_scale) +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW( a ) (a > 0) +#define GET_VERTEX(e) (imesa->verts + (e * imesa->vertex_size * sizeof(int))) + +#define VERT_SET_RGBA( v, c ) \ +do { \ + i830_color_t *color = (i830_color_t *)&((v)->ui[coloroffset]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \ +} while (0) + +#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] + +#define VERT_SET_SPEC( v0, c ) \ +do { \ + if (havespec) { \ + UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \ + } \ +} while (0) +#define VERT_COPY_SPEC( v0, v1 ) \ +do { \ + if (havespec) { \ + v0->v.specular.red = v1->v.specular.red; \ + v0->v.specular.green = v1->v.specular.green; \ + v0->v.specular.blue = v1->v.specular.blue; \ + } \ +} while (0) + +#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx] +#define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5] +#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx] + +#define LOCAL_VARS(n) \ + i830ContextPtr imesa = I830_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = (imesa->vertex_size == 4 ? 3 : 4); \ + GLboolean havespec = (imesa->vertex_size > 4); \ + (void) color; (void) spec; (void) coloroffset; (void) havespec; + + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +static const GLuint hw_prim[GL_POLYGON+1] = { + PRIM3D_POINTLIST, + PRIM3D_LINELIST, + PRIM3D_LINELIST, + PRIM3D_LINELIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST, + PRIM3D_TRILIST +}; + +#define RASTERIZE(x) if (imesa->hw_primitive != hw_prim[x]) \ + i830RasterPrimitive( ctx, x, hw_prim[x] ) +#define RENDER_PRIMITIVE imesa->render_primitive +#define TAG(x) x +#define IND I830_FALLBACK_BIT +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_OFFSET_BIT|I830_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT|I830_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_OFFSET_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_UNFILLED_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_OFFSET_BIT|I830_UNFILLED_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_UNFILLED_BIT|I830_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I830_TWOSIDE_BIT|I830_OFFSET_BIT|I830_UNFILLED_BIT| \ + I830_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + + +static void init_rast_tab( void ) +{ + init(); + init_offset(); + init_twoside(); + init_twoside_offset(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_twoside_offset_unfilled(); + init_fallback(); + init_offset_fallback(); + init_twoside_fallback(); + init_twoside_offset_fallback(); + init_unfilled_fallback(); + init_offset_unfilled_fallback(); + init_twoside_unfilled_fallback(); + init_twoside_offset_unfilled_fallback(); +} + + +/*********************************************************************** + * Rasterization fallback helpers * + ***********************************************************************/ + + +/* This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +i830_fallback_tri( i830ContextPtr imesa, + i830Vertex *v0, + i830Vertex *v1, + i830Vertex *v2 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[3]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + _swsetup_Translate( ctx, v0, &v[0] ); + _swsetup_Translate( ctx, v1, &v[1] ); + _swsetup_Translate( ctx, v2, &v[2] ); + i830SpanRenderStart( ctx ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); + i830SpanRenderFinish( ctx ); +} + + +static void +i830_fallback_line( i830ContextPtr imesa, + i830Vertex *v0, + i830Vertex *v1 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[2]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + _swsetup_Translate( ctx, v0, &v[0] ); + _swsetup_Translate( ctx, v1, &v[1] ); + i830SpanRenderStart( ctx ); + _swrast_Line( ctx, &v[0], &v[1] ); + i830SpanRenderFinish( ctx ); +} + + +static void +i830_fallback_point( i830ContextPtr imesa, + i830Vertex *v0 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[1]; + + if (0) + fprintf(stderr, "\n%s\n", __FUNCTION__); + + _swsetup_Translate( ctx, v0, &v[0] ); + i830SpanRenderStart( ctx ); + _swrast_Point( ctx, &v[0] ); + i830SpanRenderFinish( ctx ); +} + + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define IND 0 +#define V(x) (i830Vertex *)(vertptr + ((x) * vertsize * sizeof(int))) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) POINT( V(ELT(start)) ); +#define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) ) +#define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) ) +#define INIT(x) i830RenderPrimitive( ctx, x ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + i830ContextPtr imesa = I830_CONTEXT(ctx); \ + GLubyte *vertptr = (GLubyte *)imesa->verts; \ + const GLuint vertsize = imesa->vertex_size; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) x +#define TAG(x) i830_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) i830_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + + + +static void i830RenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint prim = imesa->render_primitive; + + /* Render the new vertices as an unclipped polygon. + */ + { + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, + PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; + } + + /* Restore the render primitive + */ + if (prim != GL_POLYGON) + tnl->Driver.Render.PrimitiveNotify( ctx, prim ); +} + +static void i830RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.Render.Line( ctx, ii, jj ); +} + +static void i830FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + i830ContextPtr imesa = I830_CONTEXT( ctx ); + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i830AllocDmaLow( imesa, (n-2) * 3 * 4 * vertsize ); + GLubyte *vertptr = (GLubyte *)imesa->verts; + const GLuint *start = (const GLuint *)V(elts[0]); + int i,j; + + for (i = 2 ; i < n ; i++) { + COPY_DWORDS( j, vb, vertsize, V(elts[i-1]) ); + COPY_DWORDS( j, vb, vertsize, V(elts[i]) ); + COPY_DWORDS( j, vb, vertsize, start ); + } +} + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + + + +#define _I830_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET | \ + _DD_NEW_TRI_STIPPLE | \ + _NEW_POLYGONSTIPPLE) + +#define POINT_FALLBACK (0) +#define LINE_FALLBACK (DD_LINE_STIPPLE) +#define TRI_FALLBACK (0) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\ + DD_TRI_STIPPLE) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) + +static void i830ChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + if (I830_DEBUG & DEBUG_STATE) + fprintf(stderr,"\n%s\n",__FUNCTION__); + + if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= I830_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= I830_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= I830_UNFILLED_BIT; + } + + imesa->draw_point = i830_draw_point; + imesa->draw_line = i830_draw_line; + imesa->draw_tri = i830_draw_triangle; + + /* Hook in fallbacks for specific primitives. + */ + if (flags & ANY_FALLBACK_FLAGS) + { + if (flags & POINT_FALLBACK) + imesa->draw_point = i830_fallback_point; + + if (flags & LINE_FALLBACK) + imesa->draw_line = i830_fallback_line; + + if (flags & TRI_FALLBACK) + imesa->draw_tri = i830_fallback_tri; + + if ((flags & DD_TRI_STIPPLE) && !imesa->hw_stipple) { + imesa->draw_tri = i830_fallback_tri; + } + + index |= I830_FALLBACK_BIT; + } + } + + if (imesa->RenderIndex != index) { + imesa->RenderIndex = index; + + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = i830_render_tab_verts; + tnl->Driver.Render.PrimTabElts = i830_render_tab_elts; + tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ + tnl->Driver.Render.ClippedPolygon = i830FastRenderClippedPoly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = i830RenderClippedLine; + tnl->Driver.Render.ClippedPolygon = i830RenderClippedPoly; + } + } +} + +static const GLenum reduced_prim[GL_POLYGON+1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + + +/* Determine the rasterized primitive when not drawing unfilled + * polygons. + * + * Used only for the default render stage which always decomposes + * primitives to trianges/lines/points. For the accelerated stage, + * which renders strips as strips, the equivalent calculations are + * performed in i810render.c. + */ +static void i830RenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint rprim = reduced_prim[prim]; + + imesa->render_primitive = prim; + + if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + if (imesa->reduced_primitive != rprim || + hw_prim[prim] != imesa->hw_primitive) { + i830RasterPrimitive( ctx, rprim, hw_prim[prim] ); + } +} + +static void i830RunPipeline( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + + if (imesa->NewGLState) { + if (imesa->NewGLState & _NEW_TEXTURE) { + I830_FIREVERTICES( imesa ); + i830UpdateTextureState( ctx ); /* may modify imesa->NewGLState */ + } + + if (!imesa->Fallback) { + if (imesa->NewGLState & _I830_NEW_RENDERSTATE) + i830ChooseRenderState( ctx ); + } + + imesa->NewGLState = 0; + } + + _tnl_run_pipeline( ctx ); +} + + +#define TEXCOORDTYPE_MASK (3<<11) + + + +static void set_projective_texturing( i830ContextPtr imesa, + GLuint i, + GLuint mcs) +{ + mcs |= (imesa->CurrentTexObj[i]->Setup[I830_TEXREG_MCS] & + ~TEXCOORDTYPE_MASK); + + if (mcs != imesa->CurrentTexObj[i]->Setup[I830_TEXREG_MCS]) { + I830_STATECHANGE(imesa, I830_UPLOAD_TEX_N(i)); + imesa->CurrentTexObj[i]->Setup[I830_TEXREG_MCS] = mcs; + } +} + + +#define SZ_TO_HW(sz) ((sz-2)&0x3) +#define EMIT_SZ(sz) (EMIT_1F + (sz) - 1) +#define EMIT_ATTR( ATTR, STYLE, V0 ) \ +do { \ + imesa->vertex_attrs[imesa->vertex_attr_count].attrib = (ATTR); \ + imesa->vertex_attrs[imesa->vertex_attr_count].format = (STYLE); \ + imesa->vertex_attr_count++; \ + v0 |= V0; \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + imesa->vertex_attrs[imesa->vertex_attr_count].attrib = 0; \ + imesa->vertex_attrs[imesa->vertex_attr_count].format = EMIT_PAD; \ + imesa->vertex_attrs[imesa->vertex_attr_count].offset = (N); \ + imesa->vertex_attr_count++; \ +} while (0) + +#define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2)) + +/* Make sure hardware vertex format is appropriate for VB state. + */ +static void i830RenderStart( GLcontext *ctx ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint index = tnl->render_inputs; + GLuint v0 = STATE3D_VERTEX_FORMAT_CMD; + GLuint v2 = STATE3D_VERTEX_FORMAT_2_CMD; + GLuint force_emit = 0; + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + imesa->vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to + * build up a hardware vertex. + */ + if (index & _TNL_BITS_TEX_ANY) { + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VRTX_HAS_XYZW ); + } + else { + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, VRTX_HAS_XYZ ); + } + + EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VRTX_HAS_DIFFUSE ); + + if (index & (_TNL_BIT_COLOR1|_TNL_BIT_FOG)) { + + if (index & _TNL_BIT_COLOR1) + { + if (imesa->vertex_attrs[imesa->vertex_attr_count].format != EMIT_3UB_3F_BGR) + force_emit=1; + EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VRTX_HAS_SPEC ); + } + else + { + if (imesa->vertex_attrs[imesa->vertex_attr_count].format != EMIT_PAD) + force_emit=1; + EMIT_PAD( 3 ); + } + if (index & _TNL_BIT_FOG) + { + if (imesa->vertex_attrs[imesa->vertex_attr_count].format != EMIT_1UB_1F) + force_emit=1; + EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VRTX_HAS_SPEC ); + } + else + { + if (imesa->vertex_attrs[imesa->vertex_attr_count].format != EMIT_PAD) + force_emit=1; + EMIT_PAD( 1 ); + } + } + + if (index & _TNL_BITS_TEX_ANY) { + int i, last_stage = 0; + + for (i = 0; i < ctx->Const.MaxTextureUnits ; i++) + if (index & _TNL_BIT_TEX(i)) + last_stage = i+1; + + + for (i = 0; i < last_stage; i++) { + GLuint sz = VB->TexCoordPtr[i]->size; + GLuint emit; + GLuint mcs; + + /* i830 doesn't like 1D or 4D texcoords: + */ + switch (sz) { + case 1: + case 2: + case 3: /* no attempt at cube texturing so far */ + emit = EMIT_2F; + sz = 2; + mcs = TEXCOORDTYPE_CARTESIAN; + break; + case 4: + emit = EMIT_3F_XYW; + sz = 3; + mcs = TEXCOORDTYPE_HOMOGENEOUS; + break; + default: + continue; + }; + + v2 |= VRTX_TEX_SET_FMT(i, SZ_TO_HW(sz)); + EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_SZ(sz), 0 ); + + if (imesa->CurrentTexObj[i]) + set_projective_texturing( imesa, i, mcs ); + } + + v0 |= VRTX_TEX_COORD_COUNT(last_stage); + } + + /* Only need to change the vertex emit code if there has been a + * statechange to a new hardware vertex format: + */ + if (v0 != imesa->Setup[I830_CTXREG_VF] || + v2 != imesa->Setup[I830_CTXREG_VF2] || + force_emit == 1) { + + I830_STATECHANGE( imesa, I830_UPLOAD_CTX ); + + /* Must do this *after* statechange, so as not to affect + * buffered vertices reliant on the old state: + */ + imesa->vertex_size = + _tnl_install_attrs( ctx, + imesa->vertex_attrs, + imesa->vertex_attr_count, + imesa->ViewportMatrix.m, 0 ); + + imesa->vertex_size >>= 2; + + imesa->Setup[I830_CTXREG_VF] = v0; + imesa->Setup[I830_CTXREG_VF2] = v2; + } +} + + +static void i830RenderFinish( GLcontext *ctx ) +{ + if (I830_CONTEXT(ctx)->RenderIndex & I830_FALLBACK_BIT) + _swrast_flush( ctx ); +} + + + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void i830RasterPrimitive( GLcontext *ctx, + GLenum rprim, + GLuint hwprim ) +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + GLuint aa = imesa->Setup[I830_CTXREG_AA]; + GLuint st1 = imesa->StippleSetup[I830_STPREG_ST1]; + + aa &= ~AA_LINE_ENABLE; + + if (I830_DEBUG & DEBUG_PRIMS) { + /* Prints reduced prim, and hw prim */ + char *prim_name = "Unknown"; + + switch(hwprim) { + case PRIM3D_POINTLIST: + prim_name = "PointList"; + break; + case PRIM3D_LINELIST: + prim_name = "LineList"; + break; + case PRIM3D_LINESTRIP: + prim_name = "LineStrip"; + break; + case PRIM3D_TRILIST: + prim_name = "TriList"; + break; + case PRIM3D_TRISTRIP: + prim_name = "TriStrip"; + break; + case PRIM3D_TRIFAN: + prim_name = "TriFan"; + break; + case PRIM3D_POLY: + prim_name = "Polygons"; + break; + default: + break; + } + + fprintf(stderr, "%s : rprim(%s), hwprim(%s)\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(rprim), + prim_name); + } + + switch (rprim) { + case GL_TRIANGLES: + aa |= AA_LINE_DISABLE; + if (ctx->Polygon.StippleFlag) + st1 |= ST1_ENABLE; + else + st1 &= ~ST1_ENABLE; + break; + case GL_LINES: + st1 &= ~ST1_ENABLE; + if (ctx->Line.SmoothFlag) { + aa |= AA_LINE_ENABLE; + } else { + aa |= AA_LINE_DISABLE; + } + break; + case GL_POINTS: + st1 &= ~ST1_ENABLE; + aa |= AA_LINE_DISABLE; + break; + default: + return; + } + + imesa->reduced_primitive = rprim; + + if (aa != imesa->Setup[I830_CTXREG_AA]) { + I830_STATECHANGE(imesa, I830_UPLOAD_CTX); + imesa->Setup[I830_CTXREG_AA] = aa; + } + +#if 0 + if (st1 != imesa->StippleSetup[I830_STPREG_ST1]) { + I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE); + imesa->StippleSetup[I830_STPREG_ST1] = st1; + } +#endif + + if (hwprim != imesa->hw_primitive) { + I830_STATECHANGE(imesa, 0); + imesa->hw_primitive = hwprim; + } +} + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + +static char *fallbackStrings[] = { + "Texture", + "Draw buffer", + "Read buffer", + "Color mask", + "Render mode", + "Stencil", + "Stipple", + "User disable" +}; + + +static char *getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + + + +void i830Fallback( i830ContextPtr imesa, GLuint bit, GLboolean mode ) +{ + GLcontext *ctx = imesa->glCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = imesa->Fallback; + + if (mode) { + imesa->Fallback |= bit; + if (oldfallback == 0) { + I830_FIREVERTICES(imesa); + if (I830_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "ENTER FALLBACK %s\n", getFallbackString( bit )); + _swsetup_Wakeup( ctx ); + imesa->RenderIndex = ~0; + } + } + else { + imesa->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + if (I830_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString( bit )); + tnl->Driver.Render.Start = i830RenderStart; + tnl->Driver.Render.PrimitiveNotify = i830RenderPrimitive; + tnl->Driver.Render.Finish = i830RenderFinish; + + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); + _tnl_install_attrs( ctx, + imesa->vertex_attrs, + imesa->vertex_attr_count, + imesa->ViewportMatrix.m, 0 ); + + imesa->NewGLState |= _I830_NEW_RENDERSTATE; + } + } +} + + + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +/** + * \bug + * How are the magic numbers 12 and 26 in the call to \c _tnl_init_vertices + * derived? + */ +void i830InitTriFuncs( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.RunPipeline = i830RunPipeline; + tnl->Driver.Render.Start = i830RenderStart; + tnl->Driver.Render.Finish = i830RenderFinish; + tnl->Driver.Render.PrimitiveNotify = i830RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, + 26 * sizeof(GLfloat) ); + + I830_CONTEXT(ctx)->verts = (char *)tnl->clipspace.vertex_buf; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tris.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tris.h new file mode 100644 index 000000000..ae4f0a5df --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/i830_tris.h @@ -0,0 +1,37 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Adapted for use in the I830M: + * Jeff Hartmann <jhartmann@2d3d.com> + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tris.h,v 1.3 2002/09/09 19:18:48 dawes Exp $ */ + +#ifndef I830TRIS_INC +#define I830TRIS_INC + +#include "mtypes.h" + +extern void i830PrintRenderState( const char *msg, GLuint state ); +extern void i830InitTriFuncs( GLcontext *ctx ); +extern void i830RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/server/i830_common.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/server/i830_common.h new file mode 100644 index 000000000..3367bfc16 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/server/i830_common.h @@ -0,0 +1,288 @@ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. +Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_common.h,v 1.2 2002/12/10 01:27:05 dawes Exp $ */ + +/* Author: Jeff Hartmann <jhartmann@valinux.com> + + Converted to common header format: + Jens Owen <jens@tungstengraphics.com> + */ + +#ifndef _I830_COMMON_H_ +#define _I830_COMMON_H_ + +/* WARNING: These defines must be the same as what the Xserver uses. + * if you change them, you must change the defines in the Xserver. + */ + +#ifndef _I830_DEFINES_ +#define _I830_DEFINES_ + +#define I830_DMA_BUF_ORDER 12 +#define I830_DMA_BUF_SZ (1<<I830_DMA_BUF_ORDER) +#define I830_DMA_BUF_NR 256 +#define I830_NR_SAREA_CLIPRECTS 8 + +/* Each region is a minimum of 64k, and there are at most 64 of them. + */ +#define I830_NR_TEX_REGIONS 64 +#define I830_LOG_MIN_TEX_REGION_SIZE 16 + +/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */ +#if !defined(I830_ENABLE_4_TEXTURES) +#define I830_TEXTURE_COUNT 2 +#define I830_TEXBLEND_COUNT 2 /* always same as TEXTURE_COUNT? */ +#else /* defined(I830_ENABLE_4_TEXTURES) */ +#define I830_TEXTURE_COUNT 4 +#define I830_TEXBLEND_COUNT 4 /* always same as TEXTURE_COUNT? */ +#endif /* I830_ENABLE_4_TEXTURES */ + +#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ + +#define I830_UPLOAD_CTX 0x1 +#define I830_UPLOAD_BUFFERS 0x2 +#define I830_UPLOAD_CLIPRECTS 0x4 +#define I830_UPLOAD_TEX0_IMAGE 0x100 /* handled clientside */ +#define I830_UPLOAD_TEX0_CUBE 0x200 /* handled clientside */ +#define I830_UPLOAD_TEX1_IMAGE 0x400 /* handled clientside */ +#define I830_UPLOAD_TEX1_CUBE 0x800 /* handled clientside */ +#define I830_UPLOAD_TEX2_IMAGE 0x1000 /* handled clientside */ +#define I830_UPLOAD_TEX2_CUBE 0x2000 /* handled clientside */ +#define I830_UPLOAD_TEX3_IMAGE 0x4000 /* handled clientside */ +#define I830_UPLOAD_TEX3_CUBE 0x8000 /* handled clientside */ +#define I830_UPLOAD_TEX_N_IMAGE(n) (0x100 << (n * 2)) +#define I830_UPLOAD_TEX_N_CUBE(n) (0x200 << (n * 2)) +#define I830_UPLOAD_TEXIMAGE_MASK 0xff00 +#define I830_UPLOAD_TEX0 0x10000 +#define I830_UPLOAD_TEX1 0x20000 +#define I830_UPLOAD_TEX2 0x40000 +#define I830_UPLOAD_TEX3 0x80000 +#define I830_UPLOAD_TEX_N(n) (0x10000 << (n)) +#define I830_UPLOAD_TEX_MASK 0xf0000 +#define I830_UPLOAD_TEXBLEND0 0x100000 +#define I830_UPLOAD_TEXBLEND1 0x200000 +#define I830_UPLOAD_TEXBLEND2 0x400000 +#define I830_UPLOAD_TEXBLEND3 0x800000 +#define I830_UPLOAD_TEXBLEND_N(n) (0x100000 << (n)) +#define I830_UPLOAD_TEXBLEND_MASK 0xf00000 +#define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n)) +#define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000 +#define I830_UPLOAD_STIPPLE 0x8000000 + +/* Indices into buf.Setup where various bits of state are mirrored per + * context and per buffer. These can be fired at the card as a unit, + * or in a piecewise fashion as required. + */ + +/* Destbuffer state + * - backbuffer linear offset and pitch -- invarient in the current dri + * - zbuffer linear offset and pitch -- also invarient + * - drawing origin in back and depth buffers. + * + * Keep the depth/back buffer state here to acommodate private buffers + * in the future. + */ + +#define I830_DESTREG_CBUFADDR 0 +/* Invarient */ +#define I830_DESTREG_DBUFADDR 1 +#define I830_DESTREG_DV0 2 +#define I830_DESTREG_DV1 3 +#define I830_DESTREG_SENABLE 4 +#define I830_DESTREG_SR0 5 +#define I830_DESTREG_SR1 6 +#define I830_DESTREG_SR2 7 +#define I830_DESTREG_DR0 8 +#define I830_DESTREG_DR1 9 +#define I830_DESTREG_DR2 10 +#define I830_DESTREG_DR3 11 +#define I830_DESTREG_DR4 12 +#define I830_DEST_SETUP_SIZE 13 + +/* Context state + */ +#define I830_CTXREG_STATE1 0 +#define I830_CTXREG_STATE2 1 +#define I830_CTXREG_STATE3 2 +#define I830_CTXREG_STATE4 3 +#define I830_CTXREG_STATE5 4 +#define I830_CTXREG_IALPHAB 5 +#define I830_CTXREG_STENCILTST 6 +#define I830_CTXREG_ENABLES_1 7 +#define I830_CTXREG_ENABLES_2 8 +#define I830_CTXREG_AA 9 +#define I830_CTXREG_FOGCOLOR 10 +#define I830_CTXREG_BLENDCOLR0 11 +#define I830_CTXREG_BLENDCOLR 12 /* Dword 1 of 2 dword command */ +#define I830_CTXREG_VF 13 +#define I830_CTXREG_VF2 14 +#define I830_CTXREG_MCSB0 15 +#define I830_CTXREG_MCSB1 16 +#define I830_CTX_SETUP_SIZE 17 + +/* 1.3: Stipple state + */ +#define I830_STPREG_ST0 0 +#define I830_STPREG_ST1 1 +#define I830_STP_SETUP_SIZE 2 + +/* Texture state (per tex unit) + */ +#define I830_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (6 dwords) */ +#define I830_TEXREG_MI1 1 +#define I830_TEXREG_MI2 2 +#define I830_TEXREG_MI3 3 +#define I830_TEXREG_MI4 4 +#define I830_TEXREG_MI5 5 +#define I830_TEXREG_MF 6 /* GFX_OP_MAP_FILTER */ +#define I830_TEXREG_MLC 7 /* GFX_OP_MAP_LOD_CTL */ +#define I830_TEXREG_MLL 8 /* GFX_OP_MAP_LOD_LIMITS */ +#define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */ +#define I830_TEX_SETUP_SIZE 10 + +/* New version. Kernel auto-detects. + */ +#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */ +#define I830_TEXREG_TM0S0 1 +#define I830_TEXREG_TM0S1 2 +#define I830_TEXREG_TM0S2 3 +#define I830_TEXREG_TM0S3 4 +#define I830_TEXREG_TM0S4 5 +#define I830_TEXREG_NOP0 6 /* noop */ +#define I830_TEXREG_NOP1 7 /* noop */ +#define I830_TEXREG_NOP2 8 /* noop */ +#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */ +#define __I830_TEX_SETUP_SIZE 10 + + +#define I830_FRONT 0x1 +#define I830_BACK 0x2 +#define I830_DEPTH 0x4 + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_I830_INIT 0x00 +#define DRM_I830_VERTEX 0x01 +#define DRM_I830_CLEAR 0x02 +#define DRM_I830_FLUSH 0x03 +#define DRM_I830_GETAGE 0x04 +#define DRM_I830_GETBUF 0x05 +#define DRM_I830_SWAP 0x06 +#define DRM_I830_COPY 0x07 +#define DRM_I830_DOCOPY 0x08 +#define DRM_I830_FLIP 0x09 +#define DRM_I830_IRQ_EMIT 0x0a +#define DRM_I830_IRQ_WAIT 0x0b +#define DRM_I830_GETPARAM 0x0c +#define DRM_I830_SETPARAM 0x0d + +#endif /* _I830_DEFINES_ */ + +typedef struct { + enum { + I830_INIT_DMA = 0x01, + I830_CLEANUP_DMA = 0x02 + } func; + unsigned int mmio_offset; + unsigned int buffers_offset; + int sarea_priv_offset; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; + unsigned int back_pitch; + unsigned int depth_pitch; + unsigned int cpp; +} drmI830Init; + +typedef struct { + int clear_color; + int clear_depth; + int flags; + unsigned int clear_colormask; + unsigned int clear_depthmask; +} drmI830Clear; + +/* These may be placeholders if we have more cliprects than + * I830_NR_SAREA_CLIPRECTS. In that case, the client sets discard to + * false, indicating that the buffer will be dispatched again with a + * new set of cliprects. + */ +typedef struct { + int idx; /* buffer index */ + int used; /* nr bytes in use */ + int discard; /* client is finished with the buffer? */ +} drmI830Vertex; + +typedef struct { + int idx; /* buffer index */ + int used; /* nr bytes in use */ + void *address; /* Address to copy from */ +} drmI830Copy; + +typedef struct { + void *virtual; + int request_idx; + int request_size; + int granted; +} drmI830DMA; + +typedef struct drm_i830_irq_emit { + int *irq_seq; +} drmI830IrqEmit; + +typedef struct drm_i830_irq_wait { + int irq_seq; +} drmI830IrqWait; + +typedef struct drm_i830_getparam { + int param; + int *value; +} drmI830GetParam; + +#define I830_PARAM_IRQ_ACTIVE 1 + + +typedef struct drm_i830_setparam { + int param; + int value; +} drmI830SetParam; + +#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1 + + + +#endif /* _I830_DRM_H_ */ diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/server/i830_dri.h b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/server/i830_dri.h new file mode 100644 index 000000000..e4b36cc16 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/i830/server/i830_dri.h @@ -0,0 +1,140 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.5 2002/12/10 01:27:05 dawes Exp $ */ + +#ifndef _I830_DRI_H +#define _I830_DRI_H + +#include "drm.h" /* HACK!!! why doesn't xf86drm.h work??? */ +/* #include "xf86drm.h" */ +#include "i830_common.h" + +#define I830_MAX_DRAWABLES 256 + +#define I830_MAJOR_VERSION 1 +#define I830_MINOR_VERSION 3 +#define I830_PATCHLEVEL 0 + +#define I830_REG_SIZE 0x80000 + +typedef struct _I830DRIRec { + drm_handle_t regs; + drmSize regsSize; + + drmSize backbufferSize; + drm_handle_t backbuffer; + + drmSize depthbufferSize; + drm_handle_t depthbuffer; + + drm_handle_t textures; + int textureSize; + + drm_handle_t agp_buffers; + drmSize agp_buf_size; + + int deviceID; + int width; + int height; + int mem; + int cpp; + int bitsPerPixel; + int fbOffset; + int fbStride; + + int backOffset; + int depthOffset; + + int auxPitch; + int auxPitchBits; + + int logTextureGranularity; + int textureOffset; + + /* For non-dma direct rendering. + */ + int ringOffset; + int ringSize; + + drmBufMapPtr drmBufs; + int irq; + int sarea_priv_offset; +} I830DRIRec, *I830DRIPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830ConfigPrivRec, *I830ConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} I830DRIContextRec, *I830DRIContextPtr; + +/* Warning: If you change the SAREA structure you must change the kernel + * structure as well */ + +typedef struct _I830SAREA { + unsigned int ContextState[I830_CTX_SETUP_SIZE]; + unsigned int BufferState[I830_DEST_SETUP_SIZE]; + unsigned int TexState[I830_TEXTURE_COUNT][I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed[I830_TEXBLEND_COUNT]; + unsigned int Palette[2][256]; + unsigned int dirty; + + unsigned int nbox; + drm_clip_rect_t boxes[I830_NR_SAREA_CLIPRECTS]; + + /* Maintain an LRU of contiguous regions of texture space. If + * you think you own a region of texture memory, and it has an + * age different to the one you set, then you are mistaken and + * it has been stolen by another client. If global texAge + * hasn't changed, there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained + * texture information of other clients - by maintaining them + * in the same lru which is used to age their own textures, + * clients have an approximate lru for the whole of global + * texture space, and can make informed decisions as to which + * areas to kick out. There is no need to choose whether to + * kick out your own texture or someone else's - simply eject + * them all in LRU order. + */ + + drmTextureRegion texList[I830_NR_TEX_REGIONS + 1]; + /* Last elt is sentinal */ + int texAge; /* last time texture was uploaded */ + int last_enqueue; /* last time a buffer was enqueued */ + int last_dispatch; /* age of the most recently dispatched buffer */ + int last_quiescent; /* */ + int ctxOwner; /* last context to upload state */ + + int vertex_prim; + + int pf_enabled; /* is pageflipping allowed? */ + int pf_active; /* is pageflipping active right now? */ + int pf_current_page; /* which buffer is being displayed? */ + + int perf_boxes; /* performance boxes to be displayed */ + + /* Here's the state for texunits 2,3: + */ + unsigned int TexState2[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState2[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed2; + + unsigned int TexState3[I830_TEX_SETUP_SIZE]; + unsigned int TexBlendState3[I830_TEXBLEND_SIZE]; + unsigned int TexBlendStateWordsUsed3; + + unsigned int StippleState[I830_STP_SETUP_SIZE]; +} I830SAREARec, *I830SAREAPtr; + +/* Flags for perf_boxes + */ +#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */ +#define I830_BOX_FLIP 0x2 /* populated by kernel */ +#define I830_BOX_WAIT 0x4 /* populated by kernel & client */ +#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */ +#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */ + +#endif |