From: Alan Hourihane Date: Tue, 30 Sep 2003 10:54:15 +0000 (+0000) Subject: add the i810 driver - no kernel driver yet X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=73b0420bba16b5dcfbb75b32bc519295f925041a;p=mesa.git add the i810 driver - no kernel driver yet (build tested, but not physically tested) --- diff --git a/Makefile.X11 b/Makefile.X11 index 0478ffc0601..e00c1acb17f 100644 --- a/Makefile.X11 +++ b/Makefile.X11 @@ -1,4 +1,4 @@ -# $Id: Makefile.X11,v 1.85 2003/09/09 15:08:44 brianp Exp $ +# $Id: Makefile.X11,v 1.86 2003/09/30 10:54:15 alanh Exp $ # Mesa 3-D graphics library # Version: 5.1 @@ -239,6 +239,7 @@ linux-solo: if [ -d src/mesa/drivers/dri/r128 ] ; then touch src/mesa/drivers/dri/r128/depend ; fi if [ -d src/mesa/drivers/dri/radeon ] ; then touch src/mesa/drivers/dri/radeon/depend ; fi if [ -d src/mesa/drivers/dri/mga ] ; then touch src/mesa/drivers/dri/mga/depend ; fi + if [ -d src/mesa/drivers/dri/i810 ] ; then touch src/mesa/drivers/dri/i810/depend ; fi if [ -d src/mesa/drivers/dri/fb ] ; then touch src/mesa/drivers/dri/fb/depend ; fi if [ -d src/glut/mini ] ; then touch src/glut/mini/depend ; fi if [ -d progs/miniglx ] ; then touch progs/miniglx/depend ; fi @@ -248,6 +249,7 @@ linux-solo: if [ -d src/mesa/drivers/dri/r128 ] ; then cd src/mesa/drivers/dri/r128 ; $(MAKE) -f Makefile.X11 $@ ; fi if [ -d src/mesa/drivers/dri/radeon ] ; then cd src/mesa/drivers/dri/radeon ; $(MAKE) -f Makefile.X11 $@ ; fi if [ -d src/mesa/drivers/dri/mga ] ; then cd src/mesa/drivers/dri/mga ; $(MAKE) -f Makefile.X11 $@ ; fi + if [ -d src/mesa/drivers/dri/i810 ] ; then cd src/mesa/drivers/dri/i810 ; $(MAKE) -f Makefile.X11 $@ ; fi if [ -d src/mesa/drivers/dri/fb ] ; then cd src/mesa/drivers/dri/fb ; $(MAKE) -f Makefile.X11 $@ ; fi if [ -d src/glx/mini ] ; then cd src/glx/mini ; $(MAKE) -f Makefile.X11 $@ ; fi if [ -d src/glu/mini ] ; then cd src/glu/mini ; $(MAKE) -f Makefile.X11 $@ ; fi diff --git a/src/mesa/drivers/dri/i810/Makefile.X11 b/src/mesa/drivers/dri/i810/Makefile.X11 new file mode 100644 index 00000000000..461da451e15 --- /dev/null +++ b/src/mesa/drivers/dri/i810/Makefile.X11 @@ -0,0 +1,116 @@ +# $Id: Makefile.X11,v 1.1 2003/09/30 10:54:15 alanh Exp $ + +# Mesa 3-D graphics library +# Version: 5.0 +# Copyright (C) 1995-2002 Brian Paul + +TOP = ../../../../.. + +default: linux-solo + +SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver +MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini + +DEFINES += \ + -D_HAVE_SWRAST=1 \ + -D_HAVE_SWTNL=1 \ + -D_HAVE_SANITY=1 \ + -D_HAVE_CODEGEN=1 \ + -D_HAVE_LIGHTING=1 \ + -D_HAVE_TEXGEN=1 \ + -D_HAVE_USERCLIP=1 \ + -DGLX_DIRECT_RENDERING + +# Not yet +# MINIGLX_SOURCES = server/i810_dri.c + +DRIVER_SOURCES = \ + i810context.c \ + i810ioctl.c \ + i810render.c \ + i810screen.c \ + i810span.c \ + i810state.c \ + i810tex.c \ + i810texmem.c \ + i810texstate.c \ + i810tris.c \ + i810vb.c \ + ../common/mm.c \ + ../common/utils.c \ + ../common/texmem.c \ + ../common/vblank.c + +INCLUDES = $(MINIGLX_INCLUDES) \ + $(SHARED_INCLUDES) + + +C_SOURCES = $(DRIVER_SOURCES) \ + $(MINIGLX_SOURCES) + +MESA_MODULES = $(TOP)/src/mesa/mesa.a + + +ifeq ($(WINDOW_SYSTEM),dri) +WINOBJ=$(MESABUILDDIR)/dri/dri.a +WINLIB= +else +WINOBJ= +WINLIB=-L$(MESA)/src/glx/mini +endif + +ASM_SOURCES = +OBJECTS = $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) + +### Include directories + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/transform \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup + + +##### RULES ##### + +.c.o: + $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + + +##### TARGETS ##### + +targets: depend i810_dri.so + +i810_dri.so: $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.X11 + rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc $(GL_LIB_DEPS) + rm -f $(TOP)/lib/i810_dri.so && \ + install i810_dri.so $(TOP)/lib/i810_dri.so + +# Run 'make -f Makefile.X11 dep' to update the dependencies if you change +# what's included by any source file. +depend: $(C_SOURCES) $(ASM_SOURCES) + makedepend -fdepend -Y $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) \ + $(C_SOURCES) $(ASM_SOURCES) + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.o *~ *.so server/*.o + + +include $(TOP)/Make-config + +include depend diff --git a/src/mesa/drivers/dri/i810/i810_3d_reg.h b/src/mesa/drivers/dri/i810/i810_3d_reg.h new file mode 100644 index 00000000000..dade1a826c7 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810_3d_reg.h @@ -0,0 +1,636 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810_3d_reg.h,v 1.7 2002/02/22 21:33:03 dawes Exp $ */ + +#ifndef I810_3D_REG_H +#define I810_3D_REG_H + +#include "i810_reg.h" + +/* Registers not used in the X server + */ + +#define I810_NOP_ID 0x2094 +#define I810_NOP_ID_MASK ((1<<22)-1) + + +/* 3D instructions + */ + + +/* GFXRENDERSTATE_PV_PIXELIZATION_RULE, p149 + * + * Format: + * 0: GFX_OP_PV_RULE | PV_* + * + */ +#define GFX_OP_PV_RULE ((0x3<<29)|(0x7<<24)) +#define PV_SMALL_TRI_FILTER_ENABLE (0x1<<11) +#define PV_UPDATE_PIXRULE (0x1<<10) +#define PV_PIXRULE_ENABLE (0x1<<9) +#define PV_UPDATE_LINELIST (0x1<<8) +#define PV_LINELIST_MASK (0x3<<6) +#define PV_LINELIST_PV0 (0x0<<6) +#define PV_LINELIST_PV1 (0x1<<6) +#define PV_UPDATE_TRIFAN (0x1<<5) +#define PV_TRIFAN_MASK (0x3<<3) +#define PV_TRIFAN_PV0 (0x0<<3) +#define PV_TRIFAN_PV1 (0x1<<3) +#define PV_TRIFAN_PV2 (0x2<<3) +#define PV_UPDATE_TRISTRIP (0x1<<2) +#define PV_TRISTRIP_MASK (0x3<<0) +#define PV_TRISTRIP_PV0 (0x0<<0) +#define PV_TRISTRIP_PV1 (0x1<<0) +#define PV_TRISTRIP_PV2 (0x2<<0) + + +/* GFXRENDERSTATE_SCISSOR_ENABLE, p146 + * + * Format: + * 0: GFX_OP_SCISSOR | SC_* + */ +#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19)) +#define SC_UPDATE_SCISSOR (0x1<<1) +#define SC_ENABLE_MASK (0x1<<0) +#define SC_ENABLE (0x1<<0) + +/* GFXRENDERSTATE_SCISSOR_INFO, p147 + * + * Format: + * 0: GFX_OP_SCISSOR_INFO + * 1: SCI_MIN_* + * 2: SCI_MAX_* + */ +#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1)) +#define SCI_YMIN_MASK (0xffff<<16) +#define SCI_XMIN_MASK (0xffff<<0) +#define SCI_YMAX_MASK (0xffff<<16) +#define SCI_XMAX_MASK (0xffff<<0) + +/* GFXRENDERSTATE_DRAWING_RECT_INFO, p144 + * + * Format: + * 0: GFX_OP_DRAWRECT_INFO + * 1: DR1_* + * 2: DR2_* + * 3: DR3_* + * 4: DR4_* + */ +#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) +#define DR1_RECT_CLIP_ENABLE (0x0<<31) +#define DR1_RECT_CLIP_DISABLE (0x1<<31) +#define DR1_X_DITHER_BIAS_MASK (0x3<<26) +#define DR1_X_DITHER_BIAS_SHIFT 26 +#define DR1_Y_DITHER_BIAS_MASK (0x3<<24) +#define DR1_Y_DITHER_BIAS_SHIFT 24 +#define DR2_YMIN_MASK (0xffff<<16) +#define DR2_XMIN_MASK (0xffff<<0) +#define DR3_YMAX_MASK (0xffff<<16) +#define DR3_XMAX_MASK (0xffff<<0) +#define DR4_YORG_MASK (0x3ff<<16) +#define DR4_XORG_MASK (0x7ff<<0) + + +/* GFXRENDERSTATE_LINEWIDTH_CULL_SHADE_MODE, p140 + * + * Format: + * 0: GFX_OP_LINEWIDTH_CULL_SHADE_MODE | LCS_* + */ +#define GFX_OP_LINEWIDTH_CULL_SHADE_MODE ((0x3<<29)|(0x2<<24)) +#define LCS_UPDATE_ZMODE (0x1<<20) +#define LCS_Z_MASK (0xf<<16) +#define LCS_Z_NEVER (0x1<<16) +#define LCS_Z_LESS (0x2<<16) +#define LCS_Z_EQUAL (0x3<<16) +#define LCS_Z_LEQUAL (0x4<<16) +#define LCS_Z_GREATER (0x5<<16) +#define LCS_Z_NOTEQUAL (0x6<<16) +#define LCS_Z_GEQUAL (0x7<<16) +#define LCS_Z_ALWAYS (0x8<<16) +#define LCS_UPDATE_LINEWIDTH (0x1<<15) +#define LCS_LINEWIDTH_MASK (0x7<<12) +#define LCS_LINEWIDTH_SHIFT 12 +#define LCS_LINEWIDTH_0_5 (0x1<<12) +#define LCS_LINEWIDTH_1_0 (0x2<<12) +#define LCS_LINEWIDTH_2_0 (0x4<<12) +#define LCS_LINEWIDTH_3_0 (0x6<<12) +#define LCS_UPDATE_ALPHA_INTERP (0x1<<11) +#define LCS_ALPHA_FLAT (0x1<<10) +#define LCS_ALPHA_INTERP (0x0<<10) +#define LCS_UPDATE_FOG_INTERP (0x1<<9) +#define LCS_FOG_INTERP (0x0<<8) +#define LCS_FOG_FLAT (0x1<<8) +#define LCS_UPDATE_SPEC_INTERP (0x1<<7) +#define LCS_SPEC_INTERP (0x0<<6) +#define LCS_SPEC_FLAT (0x1<<6) +#define LCS_UPDATE_RGB_INTERP (0x1<<5) +#define LCS_RGB_INTERP (0x0<<4) +#define LCS_RGB_FLAT (0x1<<4) +#define LCS_UPDATE_CULL_MODE (0x1<<3) +#define LCS_CULL_MASK (0x7<<0) +#define LCS_CULL_DISABLE (0x1<<0) +#define LCS_CULL_CW (0x2<<0) +#define LCS_CULL_CCW (0x3<<0) +#define LCS_CULL_BOTH (0x4<<0) + +#define LCS_INTERP_FLAT (LCS_ALPHA_FLAT|LCS_RGB_FLAT|LCS_SPEC_FLAT) +#define LCS_UPDATE_INTERP (LCS_UPDATE_ALPHA_INTERP| \ + LCS_UPDATE_RGB_INTERP| \ + LCS_UPDATE_SPEC_INTERP) + + +/* GFXRENDERSTATE_BOOLEAN_ENA_1, p142 + * + */ +#define GFX_OP_BOOL_1 ((0x3<<29)|(0x3<<24)) +#define B1_UPDATE_SPEC_SETUP_ENABLE (1<<19) +#define B1_SPEC_SETUP_ENABLE (1<<18) +#define B1_UPDATE_ALPHA_SETUP_ENABLE (1<<17) +#define B1_ALPHA_SETUP_ENABLE (1<<16) +#define B1_UPDATE_CI_KEY_ENABLE (1<<15) +#define B1_CI_KEY_ENABLE (1<<14) +#define B1_UPDATE_CHROMAKEY_ENABLE (1<<13) +#define B1_CHROMAKEY_ENABLE (1<<12) +#define B1_UPDATE_Z_BIAS_ENABLE (1<<11) +#define B1_Z_BIAS_ENABLE (1<<10) +#define B1_UPDATE_SPEC_ENABLE (1<<9) +#define B1_SPEC_ENABLE (1<<8) +#define B1_UPDATE_FOG_ENABLE (1<<7) +#define B1_FOG_ENABLE (1<<6) +#define B1_UPDATE_ALPHA_TEST_ENABLE (1<<5) +#define B1_ALPHA_TEST_ENABLE (1<<4) +#define B1_UPDATE_BLEND_ENABLE (1<<3) +#define B1_BLEND_ENABLE (1<<2) +#define B1_UPDATE_Z_TEST_ENABLE (1<<1) +#define B1_Z_TEST_ENABLE (1<<0) + +/* GFXRENDERSTATE_BOOLEAN_ENA_2, p143 + * + */ +#define GFX_OP_BOOL_2 ((0x3<<29)|(0x4<<24)) +#define B2_UPDATE_MAP_CACHE_ENABLE (1<<17) +#define B2_MAP_CACHE_ENABLE (1<<16) +#define B2_UPDATE_ALPHA_DITHER_ENABLE (1<<15) +#define B2_ALPHA_DITHER_ENABLE (1<<14) +#define B2_UPDATE_FOG_DITHER_ENABLE (1<<13) +#define B2_FOG_DITHER_ENABLE (1<<12) +#define B2_UPDATE_SPEC_DITHER_ENABLE (1<<11) +#define B2_SPEC_DITHER_ENABLE (1<<10) +#define B2_UPDATE_RGB_DITHER_ENABLE (1<<9) +#define B2_RGB_DITHER_ENABLE (1<<8) +#define B2_UPDATE_FB_WRITE_ENABLE (1<<3) +#define B2_FB_WRITE_ENABLE (1<<2) +#define B2_UPDATE_ZB_WRITE_ENABLE (1<<1) +#define B2_ZB_WRITE_ENABLE (1<<0) + + +/* GFXRENDERSTATE_FOG_COLOR, p144 + */ +#define GFX_OP_FOG_COLOR ((0x3<<29)|(0x15<<24)) +#define FOG_RED_SHIFT 16 +#define FOG_GREEN_SHIFT 8 +#define FOG_BLUE_SHIFT 0 +#define FOG_RESERVED_MASK ((0x7<<16)|(0x3<<8)|(0x3)) + + +/* GFXRENDERSTATE_Z_BIAS_ALPHA_FUNC_REF, p139 + */ +#define GFX_OP_ZBIAS_ALPHAFUNC ((0x3<<29)|(0x14<<24)) +#define ZA_UPDATE_ZBIAS (1<<22) +#define ZA_ZBIAS_SHIFT 14 +#define ZA_ZBIAS_MASK (0xff<<14) +#define ZA_UPDATE_ALPHAFUNC (1<<13) +#define ZA_ALPHA_MASK (0xf<<9) +#define ZA_ALPHA_NEVER (1<<9) +#define ZA_ALPHA_LESS (2<<9) +#define ZA_ALPHA_EQUAL (3<<9) +#define ZA_ALPHA_LEQUAL (4<<9) +#define ZA_ALPHA_GREATER (5<<9) +#define ZA_ALPHA_NOTEQUAL (6<<9) +#define ZA_ALPHA_GEQUAL (7<<9) +#define ZA_ALPHA_ALWAYS (8<<9) +#define ZA_UPDATE_ALPHAREF (1<<8) +#define ZA_ALPHAREF_MASK (0xff<<0) +#define ZA_ALPHAREF_SHIFT 0 +#define ZA_ALPHAREF_RESERVED (0x7<<0) + + +/* GFXRENDERSTATE_SRC_DST_BLEND_MONO, p136 + */ +#define GFX_OP_SRC_DEST_MONO ((0x3<<29)|(0x8<<24)) +#define SDM_UPDATE_MONO_ENABLE (1<<13) +#define SDM_MONO_ENABLE (1<<12) +#define SDM_UPDATE_SRC_BLEND (1<<11) +#define SDM_SRC_MASK (0xf<<6) +#define SDM_SRC_ZERO (0x1<<6) +#define SDM_SRC_ONE (0x2<<6) +#define SDM_SRC_SRC_COLOR (0x3<<6) +#define SDM_SRC_INV_SRC_COLOR (0x4<<6) +#define SDM_SRC_SRC_ALPHA (0x5<<6) +#define SDM_SRC_INV_SRC_ALPHA (0x6<<6) +#define SDM_SRC_DST_COLOR (0x9<<6) +#define SDM_SRC_INV_DST_COLOR (0xa<<6) +#define SDM_SRC_BOTH_SRC_ALPHA (0xc<<6) +#define SDM_SRC_BOTH_INV_SRC_ALPHA (0xd<<6) +#define SDM_UPDATE_DST_BLEND (1<<5) +#define SDM_DST_MASK (0xf<<0) +#define SDM_DST_ZERO (0x1<<0) +#define SDM_DST_ONE (0x2<<0) +#define SDM_DST_SRC_COLOR (0x3<<0) +#define SDM_DST_INV_SRC_COLOR (0x4<<0) +#define SDM_DST_SRC_ALPHA (0x5<<0) +#define SDM_DST_INV_SRC_ALPHA (0x6<<0) +#define SDM_DST_DST_COLOR (0x9<<0) +#define SDM_DST_INV_DST_COLOR (0xa<<0) +#define SDM_DST_BOTH_SRC_ALPHA (0xc<<0) +#define SDM_DST_BOTH_INV_SRC_ALPHA (0xd<<0) + + +/* GFXRENDERSTATE_COLOR_FACTOR, p134 + * + * Format: + * 0: GFX_OP_COLOR_FACTOR + * 1: ARGB8888 color factor + */ +#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) + +/* GFXRENDERSTATE_MAP_ALPHA_BLEND_STAGES, p132 + */ +#define GFX_OP_MAP_ALPHA_STAGES ((0x3<<29)|(0x1<<24)) +#define MA_STAGE_SHIFT 20 +#define MA_STAGE_0 (0<<20) +#define MA_STAGE_1 (1<<20) +#define MA_STAGE_2 (2<<20) +#define MA_UPDATE_ARG1 (1<<18) +#define MA_ARG1_MASK ((0x7<<15)|(0x1<<13)) +#define MA_ARG1_ALPHA_FACTOR (0x1<<15) +#define MA_ARG1_ITERATED_ALPHA (0x3<<15) +#define MA_ARG1_CURRENT_ALPHA (0x5<<15) +#define MA_ARG1_TEX0_ALPHA (0x6<<15) +#define MA_ARG1_TEX1_ALPHA (0x7<<15) +#define MA_ARG1_INVERT (0x1<<13) +#define MA_ARG1_DONT_INVERT (0x0<<13) +#define MA_UPDATE_ARG2 (1<<12) +#define MA_ARG2_MASK ((0x7<<8)|(0x1<<6)) +#define MA_ARG2_ALPHA_FACTOR (0x1<<8) +#define MA_ARG2_ITERATED_ALPHA (0x3<<8) +#define MA_ARG2_CURRENT_ALPHA (0x5<<8) +#define MA_ARG2_TEX0_ALPHA (0x6<<8) +#define MA_ARG2_TEX1_ALPHA (0x7<<8) +#define MA_ARG2_INVERT (0x1<<6) +#define MA_ARG2_DONT_INVERT (0x0<<6) +#define MA_UPDATE_OP (1<<5) +#define MA_OP_MASK (0xf) +#define MA_OP_ARG1 (0x1) +#define MA_OP_ARG2 (0x2) +#define MA_OP_MODULATE (0x3) +#define MA_OP_MODULATE_X2 (0x4) +#define MA_OP_MODULATE_X4 (0x5) +#define MA_OP_ADD (0x6) +#define MA_OP_ADD_SIGNED (0x7) +#define MA_OP_LIN_BLEND_ITER_ALPHA (0x8) +#define MA_OP_LIN_BLEND_ALPHA_FACTOR (0xa) +#define MA_OP_LIN_BLEND_TEX0_ALPHA (0x10) +#define MA_OP_LIN_BLEND_TEX1_ALPHA (0x11) + + +/* GFXRENDERSTATE_MAP_COLOR_BLEND_STAGES, p129 + */ +#define GFX_OP_MAP_COLOR_STAGES ((0x3<<29)|(0x0<<24)) +#define MC_STAGE_SHIFT 20 +#define MC_STAGE_0 (0<<20) +#define MC_STAGE_1 (1<<20) +#define MC_STAGE_2 (2<<20) +#define MC_UPDATE_DEST (1<<19) +#define MC_DEST_MASK (1<<18) +#define MC_DEST_CURRENT (0<<18) +#define MC_DEST_ACCUMULATOR (1<<18) +#define MC_UPDATE_ARG1 (1<<17) +#define MC_ARG1_MASK ((0x7<<14)|(0x1<<13)|(0x1<<12)) +#define MC_ARG1_ONE (0x0<<14) +#define MC_ARG1_COLOR_FACTOR (0x1<<14) +#define MC_ARG1_ACCUMULATOR (0x2<<14) +#define MC_ARG1_ITERATED_COLOR (0x3<<14) +#define MC_ARG1_SPECULAR_COLOR (0x4<<14) +#define MC_ARG1_CURRENT_COLOR (0x5<<14) +#define MC_ARG1_TEX0_COLOR (0x6<<14) +#define MC_ARG1_TEX1_COLOR (0x7<<14) +#define MC_ARG1_DONT_REPLICATE_ALPHA (0x0<<13) +#define MC_ARG1_REPLICATE_ALPHA (0x1<<13) +#define MC_ARG1_DONT_INVERT (0x0<<12) +#define MC_ARG1_INVERT (0x1<<12) +#define MC_UPDATE_ARG2 (1<<11) +#define MC_ARG2_MASK ((0x7<<8)|(0x1<<7)|(0x1<<6)) +#define MC_ARG2_ONE (0x0<<8) +#define MC_ARG2_COLOR_FACTOR (0x1<<8) +#define MC_ARG2_ACCUMULATOR (0x2<<8) +#define MC_ARG2_ITERATED_COLOR (0x3<<8) +#define MC_ARG2_SPECULAR_COLOR (0x4<<8) +#define MC_ARG2_CURRENT_COLOR (0x5<<8) +#define MC_ARG2_TEX0_COLOR (0x6<<8) +#define MC_ARG2_TEX1_COLOR (0x7<<8) +#define MC_ARG2_DONT_REPLICATE_ALPHA (0x0<<7) +#define MC_ARG2_REPLICATE_ALPHA (0x1<<7) +#define MC_ARG2_DONT_INVERT (0x0<<6) +#define MC_ARG2_INVERT (0x1<<6) +#define MC_UPDATE_OP (1<<5) +#define MC_OP_MASK (0xf) +#define MC_OP_DISABLE (0x0) +#define MC_OP_ARG1 (0x1) +#define MC_OP_ARG2 (0x2) +#define MC_OP_MODULATE (0x3) +#define MC_OP_MODULATE_X2 (0x4) +#define MC_OP_MODULATE_X4 (0x5) +#define MC_OP_ADD (0x6) +#define MC_OP_ADD_SIGNED (0x7) +#define MC_OP_LIN_BLEND_ITER_ALPHA (0x8) +#define MC_OP_LIN_BLEND_ALPHA_FACTOR (0xa) +#define MC_OP_LIN_BLEND_TEX0_ALPHA (0x10) +#define MC_OP_LIN_BLEND_TEX1_ALPHA (0x11) +#define MC_OP_LIN_BLEND_TEX0_COLOR (0x12) +#define MC_OP_LIN_BLEND_TEX1_COLOR (0x13) +#define MC_OP_SUBTRACT (0x14) + +/* GFXRENDERSTATE_MAP_PALETTE_LOAD, p128 + * + * Format: + * 0: GFX_OP_MAP_PALETTE_LOAD + * 1: 16bpp color[0] + * ... + * 256: 16bpp color[255] + */ +#define GFX_OP_MAP_PALETTE_LOAD ((0x3<<29)|(0x1d<<24)|(0x82<<16)|0xff) + +/* GFXRENDERSTATE_MAP_LOD_CONTROL, p127 + */ +#define GFX_OP_MAP_LOD_CTL ((0x3<<29)|(0x1c<<24)|(0x4<<19)) +#define MLC_MAP_ID_SHIFT 16 +#define MLC_MAP_0 (0<<16) +#define MLC_MAP_1 (1<<16) +#define MLC_UPDATE_DITHER_WEIGHT (1<<10) +#define MLC_DITHER_WEIGHT_MASK (0x3<<8) +#define MLC_DITHER_WEIGHT_FULL (0x0<<8) +#define MLC_DITHER_WEIGHT_50 (0x1<<8) +#define MLC_DITHER_WEIGHT_25 (0x2<<8) +#define MLC_DITHER_WEIGHT_12 (0x3<<8) +#define MLC_UPDATE_LOD_BIAS (1<<7) +#define MLC_LOD_BIAS_MASK ((1<<7)-1) + +/* GFXRENDERSTATE_MAP_LOD_LIMITS, p126 + */ +#define GFX_OP_MAP_LOD_LIMITS ((0x3<<29)|(0x1c<<24)|(0x3<<19)) +#define MLL_MAP_ID_SHIFT 16 +#define MLL_MAP_0 (0<<16) +#define MLL_MAP_1 (1<<16) +#define MLL_UPDATE_MAX_MIP (1<<13) +#define MLL_MAX_MIP_SHIFT 5 +#define MLL_MAX_MIP_MASK (0xff<<5) +#define MLL_MAX_MIP_ONE (0x10<<5) +#define MLL_UPDATE_MIN_MIP (1<<4) +#define MLL_MIN_MIP_SHIFT 0 +#define MLL_MIN_MIP_MASK (0xf<<0) + +/* GFXRENDERSTATE_MAP_FILTER, p124 + */ +#define GFX_OP_MAP_FILTER ((0x3<<29)|(0x1c<<24)|(0x2<<19)) +#define MF_MAP_ID_SHIFT 16 +#define MF_MAP_0 (0<<16) +#define MF_MAP_1 (1<<16) +#define MF_UPDATE_ANISOTROPIC (1<<12) +#define MF_ANISOTROPIC_MASK (1<<10) +#define MF_ANISOTROPIC_ENABLE (1<<10) +#define MF_UPDATE_MIP_FILTER (1<<9) +#define MF_MIP_MASK (0x3<<6) +#define MF_MIP_NONE (0x0<<6) +#define MF_MIP_NEAREST (0x1<<6) +#define MF_MIP_DITHER (0x2<<6) +#define MF_MIP_LINEAR (0x3<<6) +#define MF_UPDATE_MAG_FILTER (1<<5) +#define MF_MAG_MASK (1<<3) +#define MF_MAG_LINEAR (1<<3) +#define MF_MAG_NEAREST (0<<3) +#define MF_UPDATE_MIN_FILTER (1<<2) +#define MF_MIN_MASK (1<<0) +#define MF_MIN_LINEAR (1<<0) +#define MF_MIN_NEAREST (0<<0) + +/* GFXRENDERSTATE_MAP_INFO, p118 + */ +#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x2) +#define MI1_MAP_ID_SHIFT 28 +#define MI1_MAP_0 (0<<28) +#define MI1_MAP_1 (1<<28) +#define MI1_FMT_MASK (0x7<<24) +#define MI1_FMT_8CI (0x0<<24) +#define MI1_FMT_8BPP (0x1<<24) +#define MI1_FMT_16BPP (0x2<<24) +#define MI1_FMT_422 (0x5<<24) +#define MI1_PF_MASK (0x3<<21) +#define MI1_PF_8CI_RGB565 (0x0<<21) +#define MI1_PF_8CI_ARGB1555 (0x1<<21) +#define MI1_PF_8CI_ARGB4444 (0x2<<21) +#define MI1_PF_8CI_AY88 (0x3<<21) +#define MI1_PF_16BPP_RGB565 (0x0<<21) +#define MI1_PF_16BPP_ARGB1555 (0x1<<21) +#define MI1_PF_16BPP_ARGB4444 (0x2<<21) +#define MI1_PF_16BPP_AY88 (0x3<<21) +#define MI1_PF_422_YCRCB_SWAP_Y (0x0<<21) +#define MI1_PF_422_YCRCB (0x1<<21) +#define MI1_PF_422_YCRCB_SWAP_UV (0x2<<21) +#define MI1_PF_422_YCRCB_SWAP_YUV (0x3<<21) +#define MI1_OUTPUT_CHANNEL_MASK (0x3<<19) +#define MI1_COLOR_CONV_ENABLE (1<<18) +#define MI1_VERT_STRIDE_MASK (1<<17) +#define MI1_VERT_STRIDE_1 (1<<17) +#define MI1_VERT_OFFSET_MASK (1<<16) +#define MI1_VERT_OFFSET_1 (1<<16) +#define MI1_ENABLE_FENCE_REGS (1<<10) +#define MI1_TILED_SURFACE (1<<9) +#define MI1_TILE_WALK_X (0<<8) +#define MI1_TILE_WALK_Y (1<<8) +#define MI1_PITCH_MASK (0xf<<0) +#define MI2_DIMENSIONS_ARE_LOG2 (1<<31) +#define MI2_DIMENSIONS_ARE_EXACT (0<<31) +#define MI2_HEIGHT_SHIFT 16 +#define MI2_HEIGHT_MASK (0x1ff<<16) +#define MI2_WIDTH_SHIFT 0 +#define MI2_WIDTH_MASK (0x1ff<<0) +#define MI3_BASE_ADDR_MASK (~0xf) + +/* GFXRENDERSTATE_MAP_COORD_SETS, p116 + */ +#define GFX_OP_MAP_COORD_SETS ((0x3<<29)|(0x1c<<24)|(0x1<<19)) +#define MCS_COORD_ID_SHIFT 16 +#define MCS_COORD_0 (0<<16) +#define MCS_COORD_1 (1<<16) +#define MCS_UPDATE_NORMALIZED (1<<15) +#define MCS_NORMALIZED_COORDS_MASK (1<<14) +#define MCS_NORMALIZED_COORDS (1<<14) +#define MCS_UPDATE_V_STATE (1<<7) +#define MCS_V_STATE_MASK (0x3<<4) +#define MCS_V_WRAP (0x0<<4) +#define MCS_V_MIRROR (0x1<<4) +#define MCS_V_CLAMP (0x2<<4) +#define MCS_V_WRAP_SHORTEST (0x3<<4) +#define MCS_UPDATE_U_STATE (1<<3) +#define MCS_U_STATE_MASK (0x3<<0) +#define MCS_U_WRAP (0x0<<0) +#define MCS_U_MIRROR (0x1<<0) +#define MCS_U_CLAMP (0x2<<0) +#define MCS_U_WRAP_SHORTEST (0x3<<0) + +/* GFXRENDERSTATE_MAP_TEXELS, p115 + */ +#define GFX_OP_MAP_TEXELS ((0x3<<29)|(0x1c<<24)|(0x0<<19)) +#define MT_UPDATE_TEXEL1_STATE (1<<15) +#define MT_TEXEL1_DISABLE (0<<14) +#define MT_TEXEL1_ENABLE (1<<14) +#define MT_TEXEL1_COORD0 (0<<11) +#define MT_TEXEL1_COORD1 (1<<11) +#define MT_TEXEL1_MAP0 (0<<8) +#define MT_TEXEL1_MAP1 (1<<8) +#define MT_UPDATE_TEXEL0_STATE (1<<7) +#define MT_TEXEL0_DISABLE (0<<6) +#define MT_TEXEL0_ENABLE (1<<6) +#define MT_TEXEL0_COORD0 (0<<3) +#define MT_TEXEL0_COORD1 (1<<3) +#define MT_TEXEL0_MAP0 (0<<0) +#define MT_TEXEL0_MAP1 (1<<0) + +/* GFXRENDERSTATE_VERTEX_FORMAT, p110 + */ +#define GFX_OP_VERTEX_FMT ((0x3<<29)|(0x5<<24)) +#define VF_TEXCOORD_COUNT_SHIFT 8 +#define VF_TEXCOORD_COUNT_0 (0<<8) +#define VF_TEXCOORD_COUNT_1 (1<<8) +#define VF_TEXCOORD_COUNT_2 (2<<8) +#define VF_SPEC_FOG_ENABLE (1<<7) +#define VF_RGBA_ENABLE (1<<6) +#define VF_Z_OFFSET_ENABLE (1<<5) +#define VF_XYZ (0x1<<1) +#define VF_XYZW (0x2<<1) +#define VF_XY (0x3<<1) +#define VF_XYW (0x4<<1) + + +#define VERT_X_MASK (~0xf) +#define VERT_X_EDGE_V2V0 (1<<2) +#define VERT_X_EDGE_V1V2 (1<<1) +#define VERT_X_EDGE_V0V1 (1<<0) + +/* Not enabled fields should not be sent to hardware: + */ +typedef struct { + union { + float x; + unsigned int edge_flags; + } x; + float y; + float z; + float z_bias; + float oow; + unsigned int argb; + unsigned int fog_spec_rgb; /* spec g and r ignored. */ + float tu0; + float tv0; + float tu1; + float tv1; +} i810_full_vertex; + + + +/* GFXCMDPARSER_BATCH_BUFFER, p105 + * + * Not clear whether start address must be shifted or not. Not clear + * whether address is physical system memory, or subject to GTT + * translation. Because the address appears to be 32 bits long, + * perhaps it refers to physical system memory... + */ +#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1) +#define BB1_START_ADDR_MASK (~0x7) +#define BB1_PROTECTED (1<<0) +#define BB1_UNPROTECTED (0<<0) +#define BB2_END_ADDR_MASK (~0x7) + +/* Hardware seems to barf on buffers larger than this (in strange ways)... + */ +#define MAX_BATCH (512*1024) + + +/* GFXCMDPARSER_Z_BUFFER_INFO, p98 + * + * Base address is in GTT space, and must be 4K aligned + */ +#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) +#define ZB_BASE_ADDR_SHIFT 0 +#define ZB_BASE_ADDR_MASK (~((1<<12)-1)) +#define ZB_PITCH_512B (0x0<<0) +#define ZB_PITCH_1K (0x1<<0) +#define ZB_PITCH_2K (0x2<<0) +#define ZB_PITCH_4K (0x3<<0) + +/* GFXCMDPARSER_FRONT_BUFFER_INFO, p97 + * + * Format: + * 0: CMD_OP_FRONT_BUFFER_INFO | (pitch< + * + */ + + +#include "glheader.h" +#include "context.h" +#include "matrix.h" +#include "simple_list.h" +#include "extensions.h" +#include "imports.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "array_cache/acache.h" + +#include "tnl/t_pipeline.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810state.h" +#include "i810tex.h" +#include "i810span.h" +#include "i810tris.h" +#include "i810vb.h" +#include "i810ioctl.h" + +#include "utils.h" +#ifndef I810_DEBUG +int I810_DEBUG = (0); +#endif + +static const GLubyte *i810GetString( GLcontext *ctx, GLenum name ) +{ + switch (name) { + case GL_VENDOR: + return (GLubyte *)"Keith Whitwell"; + case GL_RENDERER: + return (GLubyte *)"Mesa DRI I810 20021125"; + default: + return 0; + } +} + +static void i810BufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) +{ + GET_CURRENT_CONTEXT(ctx); + i810ContextPtr imesa = I810_CONTEXT(ctx); + + /* Need to lock to make sure the driDrawable is uptodate. This + * information is used to resize Mesa's software buffers, so it has + * to be correct. + */ + LOCK_HARDWARE(imesa); + *width = imesa->driDrawable->w; + *height = imesa->driDrawable->h; + UNLOCK_HARDWARE(imesa); +} + +/* Extension strings exported by the i810 driver. + */ +static const char * const card_extensions[] = +{ + "GL_ARB_multitexture", + "GL_ARB_texture_env_add", + "GL_ARB_texture_mirrored_repeat", + "GL_EXT_stencil_wrap", + "GL_EXT_texture_edge_clamp", + "GL_EXT_texture_env_add", + "GL_EXT_texture_lod_bias", + "GL_IBM_texture_mirrored_repeat", + "GL_MESA_ycbcr_texture", + "GL_SGIS_generate_mipmap", + "GL_SGIS_texture_edge_clamp", + NULL +}; + +extern const struct gl_pipeline_stage _i810_render_stage; + +static const struct gl_pipeline_stage *i810_pipeline[] = { + &_tnl_vertex_transform_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + /* REMOVE: point attenuation stage */ +#if 1 + &_i810_render_stage, /* ADD: unclipped rastersetup-to-dma */ +#endif + &_tnl_render_stage, + 0, +}; + +static const struct dri_debug_control debug_control[] = +{ + { "fall", DEBUG_FALLBACKS }, + { "tex", DEBUG_TEXTURE }, + { "ioctl", DEBUG_IOCTL }, + { "prim", DEBUG_PRIMS }, + { "vert", DEBUG_VERTS }, + { "state", DEBUG_STATE }, + { "verb", DEBUG_VERBOSE }, + { "dri", DEBUG_DRI }, + { "dma", DEBUG_DMA }, + { "san", DEBUG_SANITY }, + { "sync", DEBUG_SYNC }, + { "sleep", DEBUG_SLEEP }, + { NULL, 0 } +}; + +GLboolean +i810CreateContext( const __GLcontextModes *mesaVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ) +{ + GLcontext *ctx, *shareCtx; + i810ContextPtr imesa; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private; + I810SAREAPtr saPriv = (I810SAREAPtr) + (((GLubyte *)sPriv->pSAREA) + i810Screen->sarea_priv_offset); + + /* Allocate i810 context */ + imesa = (i810ContextPtr) CALLOC_STRUCT(i810_context_t); + if (!imesa) { + return GL_FALSE; + } + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((i810ContextPtr) sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + imesa->glCtx = _mesa_create_context(mesaVis, shareCtx, (void*) imesa, GL_TRUE); + if (!imesa->glCtx) { + FREE(imesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = imesa; + + imesa->i810Screen = i810Screen; + imesa->driScreen = sPriv; + imesa->sarea = saPriv; + imesa->glBuffer = NULL; + + (void) memset( imesa->texture_heaps, 0, sizeof( imesa->texture_heaps ) ); + make_empty_list( & imesa->swapped ); + + imesa->nr_heaps = 1; + imesa->texture_heaps[0] = driCreateTextureHeap( 0, imesa, + i810Screen->textureSize, + 12, + I810_NR_TEX_REGIONS, + imesa->sarea->texList, + & imesa->sarea->texAge, + & imesa->swapped, + sizeof( struct i810_texture_object_t ), + (destroy_texture_object_t *) i810DestroyTexObj ); + + + + /* Set the maximum texture size small enough that we can guarentee + * that both texture units can bind a maximal texture and have them + * in memory at once. + */ + + + + ctx = imesa->glCtx; + ctx->Const.MaxTextureUnits = 2; + + + /* FIXME: driCalcualteMaxTextureLevels assumes that mipmaps are tightly + * FIXME: packed, but they're not in Intel graphics hardware. + */ + driCalculateMaxTextureLevels( imesa->texture_heaps, + imesa->nr_heaps, + & ctx->Const, + 4, + 11, /* max 2D texture size is 2048x2048 */ + 0, /* 3D textures unsupported */ + 0, /* cube textures unsupported. */ + 0, /* texture rectangles unsupported. */ + 12, + GL_FALSE ); + + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = 3.0; + ctx->Const.MaxLineWidthAA = 3.0; + ctx->Const.LineWidthGranularity = 1.0; + + ctx->Const.MinPointSize = 1.0; + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSize = 3.0; + ctx->Const.MaxPointSizeAA = 3.0; + ctx->Const.PointSizeGranularity = 1.0; + + ctx->Driver.GetBufferSize = i810BufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; + ctx->Driver.GetString = i810GetString; + + /* 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, i810_pipeline ); + + /* Configure swrast to match hardware characteristics: + */ + _swrast_allow_pixel_fog( ctx, GL_FALSE ); + _swrast_allow_vertex_fog( ctx, GL_TRUE ); + + /* Dri stuff + */ + imesa->hHWContext = driContextPriv->hHWContext; + imesa->driFd = sPriv->fd; + imesa->driHwLock = &sPriv->pSAREA->lock; + + imesa->stipple_in_hw = 1; + imesa->RenderIndex = ~0; + imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS; + imesa->upload_cliprects = GL_TRUE; + + imesa->CurrentTexObj[0] = 0; + imesa->CurrentTexObj[1] = 0; + + _math_matrix_ctr( &imesa->ViewportMatrix ); + + driInitExtensions( ctx, card_extensions, GL_TRUE ); + i810InitStateFuncs( ctx ); + i810InitTextureFuncs( ctx ); + i810InitTriFuncs( ctx ); + i810InitSpanFuncs( ctx ); + i810InitIoctlFuncs( ctx ); + i810InitVB( ctx ); + i810InitState( ctx ); + +#if DO_DEBUG + I810_DEBUG = driParseDebugString( getenv( "I810_DEBUG" ), + debug_control ); + I810_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ), + debug_control ); +#endif + + return GL_TRUE; +} + +void +i810DestroyContext(__DRIcontextPrivate *driContextPriv) +{ + i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate; + + assert(imesa); /* should never be null */ + if (imesa) { + GLboolean release_texture_heaps; + + + release_texture_heaps = (imesa->glCtx->Shared->RefCount == 1); + _swsetup_DestroyContext( imesa->glCtx ); + _tnl_DestroyContext( imesa->glCtx ); + _ac_DestroyContext( imesa->glCtx ); + _swrast_DestroyContext( imesa->glCtx ); + + i810FreeVB( imesa->glCtx ); + + /* free the Mesa context */ + imesa->glCtx->DriverCtx = NULL; + _mesa_destroy_context(imesa->glCtx); + if ( release_texture_heaps ) { + /* This share group is about to go away, free our private + * texture object data. + */ + int i; + + assert( is_empty_list( & imesa->swapped ) ); + + for ( i = 0 ; i < imesa->nr_heaps ; i++ ) { + driDestroyTextureHeap( imesa->texture_heaps[ i ] ); + imesa->texture_heaps[ i ] = NULL; + } + } + + Xfree(imesa); + } +} + + +void i810XMesaSetFrontClipRects( i810ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + + imesa->numClipRects = dPriv->numClipRects; + imesa->pClipRects = dPriv->pClipRects; + imesa->drawX = dPriv->x; + imesa->drawY = dPriv->y; + + i810EmitDrawingRectangle( imesa ); + imesa->upload_cliprects = GL_TRUE; +} + + +void i810XMesaSetBackClipRects( i810ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + + if (imesa->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) + { + imesa->numClipRects = dPriv->numClipRects; + imesa->pClipRects = dPriv->pClipRects; + imesa->drawX = dPriv->x; + imesa->drawY = dPriv->y; + } else { + imesa->numClipRects = dPriv->numBackClipRects; + imesa->pClipRects = dPriv->pBackClipRects; + imesa->drawX = dPriv->backX; + imesa->drawY = dPriv->backY; + } + + i810EmitDrawingRectangle( imesa ); + imesa->upload_cliprects = GL_TRUE; +} + + +static void i810XMesaWindowMoved( i810ContextPtr imesa ) +{ + switch (imesa->glCtx->Color._DrawDestMask) { + case FRONT_LEFT_BIT: + i810XMesaSetFrontClipRects( imesa ); + break; + case BACK_LEFT_BIT: + i810XMesaSetBackClipRects( imesa ); + break; + case GL_FRONT_LEFT: + default: + /* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */ + i810XMesaSetFrontClipRects( imesa ); + } +} + + +GLboolean +i810UnbindContext(__DRIcontextPrivate *driContextPriv) +{ + i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate; + if (imesa) { + imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS; + if (imesa->CurrentTexObj[0]) imesa->dirty |= I810_UPLOAD_TEX0; + if (imesa->CurrentTexObj[1]) imesa->dirty |= I810_UPLOAD_TEX1; + } + + return GL_TRUE; +} + + +GLboolean +i810MakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + if (driContextPriv) { + i810ContextPtr imesa = (i810ContextPtr) driContextPriv->driverPrivate; + + /* Shouldn't the readbuffer be stored also? + */ + imesa->driDrawable = driDrawPriv; + + _mesa_make_current2(imesa->glCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate); + + /* Are these necessary? + */ + i810XMesaWindowMoved( imesa ); + if (!imesa->glCtx->Viewport.Width) + _mesa_set_viewport(imesa->glCtx, 0, 0, + driDrawPriv->w, driDrawPriv->h); + } + else { + _mesa_make_current(0,0); + } + + return GL_TRUE; +} + +static void +i810UpdatePageFlipping( i810ContextPtr imesa ) +{ + GLcontext *ctx = imesa->glCtx; + int front = 0; + + switch (ctx->Color._DrawDestMask) { + case FRONT_LEFT_BIT: + front = 1; + break; + case BACK_LEFT_BIT: + front = 0; + break; + default: + return; + } + + if ( imesa->sarea->pf_current_page == 1 ) + front ^= 1; + + if (front) { + imesa->BufferSetup[I810_DESTREG_DI1] = imesa->i810Screen->fbOffset | imesa->i810Screen->backPitchBits; + imesa->drawMap = (char *)imesa->driScreen->pFB; + imesa->readMap = (char *)imesa->driScreen->pFB; + } else { + imesa->BufferSetup[I810_DESTREG_DI1] = imesa->i810Screen->backOffset | imesa->i810Screen->backPitchBits; + imesa->drawMap = imesa->i810Screen->back.map; + imesa->readMap = imesa->i810Screen->back.map; + } + + imesa->dirty |= I810_UPLOAD_BUFFERS; +} + +void i810GetLock( i810ContextPtr imesa, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + __DRIscreenPrivate *sPriv = imesa->driScreen; + I810SAREAPtr sarea = imesa->sarea; + int me = imesa->hHWContext; + unsigned i; + + drmGetLock(imesa->driFd, imesa->hHWContext, flags); + + /* If the window moved, may need to set a new cliprect now. + * + * NOTE: This releases and regains the hw lock, so all state + * checking must be done *after* this call: + */ + DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); + + + /* If we lost context, need to dump all registers to hardware. + * Note that we don't care about 2d contexts, even if they perform + * accelerated commands, so the DRI locking in the X server is even + * more broken than usual. + */ + if (sarea->ctxOwner != me) { + imesa->upload_cliprects = GL_TRUE; + imesa->dirty = I810_UPLOAD_CTX|I810_UPLOAD_BUFFERS; + if (imesa->CurrentTexObj[0]) imesa->dirty |= I810_UPLOAD_TEX0; + if (imesa->CurrentTexObj[1]) imesa->dirty |= I810_UPLOAD_TEX1; + sarea->ctxOwner = me; + } + + /* Shared texture managment - if another client has played with + * texture space, figure out which if any of our textures have been + * ejected, and update our global LRU. + */ + for ( i = 0 ; i < imesa->nr_heaps ; i++ ) { + DRI_AGE_TEXTURES( imesa->texture_heaps[ i ] ); + } + + if (imesa->lastStamp != dPriv->lastStamp) { + i810UpdatePageFlipping( imesa ); + i810XMesaWindowMoved( imesa ); + imesa->lastStamp = dPriv->lastStamp; + } +} + + +void +i810SwapBuffers( __DRIdrawablePrivate *dPriv ) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + i810ContextPtr imesa; + GLcontext *ctx; + imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate; + ctx = imesa->glCtx; + if (ctx->Visual.doubleBufferMode) { + _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ + if ( imesa->sarea->pf_active ) { + i810PageFlip( dPriv ); + } else { + i810CopyBuffer( dPriv ); + } + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + _mesa_problem(NULL, "i810SwapBuffers: drawable has no context!\n"); + } +} + diff --git a/src/mesa/drivers/dri/i810/i810context.h b/src/mesa/drivers/dri/i810/i810context.h new file mode 100644 index 00000000000..b24bd7ca343 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810context.h @@ -0,0 +1,256 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810context.h,v 1.9 2002/12/16 16:18:51 dawes Exp $ */ + +#ifndef I810CONTEXT_INC +#define I810CONTEXT_INC + +typedef struct i810_context_t i810Context; +typedef struct i810_context_t *i810ContextPtr; +typedef struct i810_texture_object_t *i810TextureObjectPtr; + +#include "mtypes.h" +#include "mm.h" + +#include "i810screen.h" +#include "i810tex.h" + + +/* Reasons to disable hardware rasterization. + */ +#define I810_FALLBACK_TEXTURE 0x1 +#define I810_FALLBACK_DRAW_BUFFER 0x2 +#define I810_FALLBACK_READ_BUFFER 0x4 +#define I810_FALLBACK_COLORMASK 0x8 +#define I810_FALLBACK_SPECULAR 0x20 +#define I810_FALLBACK_LOGICOP 0x40 +#define I810_FALLBACK_RENDERMODE 0x80 +#define I810_FALLBACK_STENCIL 0x100 +#define I810_FALLBACK_BLEND_EQ 0x200 +#define I810_FALLBACK_BLEND_FUNC 0x400 + + +#ifndef PCI_CHIP_I810 +#define PCI_CHIP_I810 0x7121 +#define PCI_CHIP_I810_DC100 0x7123 +#define PCI_CHIP_I810_E 0x7125 +#define PCI_CHIP_I815 0x1132 +#endif + +#define IS_I810(imesa) (imesa->i810Screen->deviceID == PCI_CHIP_I810 || \ + imesa->i810Screen->deviceID == PCI_CHIP_I810_DC100 || \ + imesa->i810Screen->deviceID == PCI_CHIP_I810_E) +#define IS_I815(imesa) (imesa->i810Screen->deviceID == PCI_CHIP_I815) + + +#define I810_UPLOAD_TEX(i) (I810_UPLOAD_TEX0<<(i)) + +/* Use the templated vertex formats: + */ +#define TAG(x) i810##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +typedef void (*i810_tri_func)( i810ContextPtr, i810Vertex *, i810Vertex *, + i810Vertex * ); +typedef void (*i810_line_func)( i810ContextPtr, i810Vertex *, i810Vertex * ); +typedef void (*i810_point_func)( i810ContextPtr, i810Vertex * ); + +struct i810_context_t { + GLint refcount; + GLcontext *glCtx; + + /* Texture object bookkeeping + */ + unsigned nr_heaps; + driTexHeap * texture_heaps[1]; + driTextureObject swapped; + + struct i810_texture_object_t *CurrentTexObj[2]; + + + /* Bit flag to keep track of fallbacks. + */ + GLuint Fallback; + + /* Temporaries for translating away float colors: + */ + struct gl_client_array UbyteColor; + struct gl_client_array UbyteSecondaryColor; + + /* State for i810vb.c and i810tris.c. + */ + GLuint new_state; /* _NEW_* flags */ + GLuint SetupNewInputs; + GLuint SetupIndex; + GLuint RenderIndex; + GLmatrix ViewportMatrix; + GLenum render_primitive; + GLenum reduced_primitive; + GLuint hw_primitive; + GLubyte *verts; + + drmBufPtr vertex_buffer; + char *vertex_addr; + GLuint vertex_low; + GLuint vertex_high; + GLuint vertex_last_prim; + + GLboolean upload_cliprects; + + + /* Fallback rasterization functions + */ + i810_point_func draw_point; + i810_line_func draw_line; + i810_tri_func draw_tri; + + /* Hardware state + */ + GLuint dirty; /* I810_UPLOAD_* */ + GLuint Setup[I810_CTX_SETUP_SIZE]; + GLuint BufferSetup[I810_DEST_SETUP_SIZE]; + int vertex_size; + int vertex_stride_shift; + unsigned int lastStamp; + GLboolean stipple_in_hw; + + GLenum TexEnvImageFmt[2]; + + /* State which can't be computed completely on the fly: + */ + GLuint LcsCullMode; + GLuint LcsLineWidth; + GLuint LcsPointSize; + + /* Funny mesa mirrors + */ + GLushort ClearColor; + + /* DRI stuff + */ + GLuint needClip; + GLframebuffer *glBuffer; + GLboolean doPageFlip; + + /* These refer to the current draw (front vs. back) buffer: + */ + char *drawMap; /* draw buffer address in virtual mem */ + char *readMap; + int drawX; /* origin of drawable in draw buffer */ + int drawY; + GLuint numClipRects; /* cliprects for that buffer */ + XF86DRIClipRectPtr pClipRects; + + int lastSwap; + int texAge; + int ctxAge; + int dirtyAge; + + + GLboolean scissor; + XF86DRIClipRectRec draw_rect; + XF86DRIClipRectRec scissor_rect; + + drmContext hHWContext; + drmLock *driHwLock; + int driFd; + + __DRIdrawablePrivate *driDrawable; + __DRIscreenPrivate *driScreen; + i810ScreenPrivate *i810Screen; + I810SAREAPtr sarea; +}; + + +#define I810_CONTEXT(ctx) ((i810ContextPtr)(ctx->DriverCtx)) + +#define GET_DISPATCH_AGE( imesa ) imesa->sarea->last_dispatch +#define GET_ENQUEUE_AGE( imesa ) imesa->sarea->last_enqueue + + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( imesa ) \ + do { \ + char __ret=0; \ + DRM_CAS(imesa->driHwLock, imesa->hHWContext, \ + (DRM_LOCK_HELD|imesa->hHWContext), __ret); \ + if (__ret) \ + i810GetLock( imesa, 0 ); \ + } while (0) + + + +/* Release the kernel lock. + */ +#define UNLOCK_HARDWARE(imesa) \ + DRM_UNLOCK(imesa->driFd, imesa->driHwLock, imesa->hHWContext); + + +/* This is the wrong way to do it, I'm sure. Otherwise the drm + * bitches that I've already got the heavyweight lock. At worst, + * this is 3 ioctls. The best solution probably only gets me down + * to 2 ioctls in the worst case. + */ +#define LOCK_HARDWARE_QUIESCENT( imesa ) do { \ + LOCK_HARDWARE( imesa ); \ + i810RegetLockQuiescent( imesa ); \ +} while(0) + + +extern void i810GetLock( i810ContextPtr imesa, GLuint flags ); +extern void i810EmitHwStateLocked( i810ContextPtr imesa ); +extern void i810EmitScissorValues( i810ContextPtr imesa, int box_nr, int emit ); +extern void i810EmitDrawingRectangle( i810ContextPtr imesa ); +extern void i810XMesaSetBackClipRects( i810ContextPtr imesa ); +extern void i810XMesaSetFrontClipRects( i810ContextPtr imesa ); + +#define SUBPIXEL_X -.5 +#define SUBPIXEL_Y -.5 + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 1 +#if DO_DEBUG +extern int I810_DEBUG; +#else +#define I810_DEBUG 0 +#endif + +#define DEBUG_TEXTURE 0x1 +#define DEBUG_STATE 0x2 +#define DEBUG_IOCTL 0x4 +#define DEBUG_PRIMS 0x8 +#define DEBUG_VERTS 0x10 +#define DEBUG_FALLBACKS 0x20 +#define DEBUG_VERBOSE 0x40 +#define DEBUG_DRI 0x80 +#define DEBUG_DMA 0x100 +#define DEBUG_SANITY 0x200 +#define DEBUG_SYNC 0x400 +#define DEBUG_SLEEP 0x800 + +#endif diff --git a/src/mesa/drivers/dri/i810/i810ioctl.c b/src/mesa/drivers/dri/i810/i810ioctl.c new file mode 100644 index 00000000000..d769d58d566 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810ioctl.c @@ -0,0 +1,510 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.c,v 1.7 2002/10/30 12:51:33 alanh Exp $ */ + +#include /* for usleep() */ + +#include "glheader.h" +#include "mtypes.h" +#include "macros.h" +#include "dd.h" +#include "swrast/swrast.h" +#include "mm.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810context.h" +#include "i810ioctl.h" +#include "i810state.h" + +static drmBufPtr i810_get_buffer_ioctl( i810ContextPtr imesa ) +{ + drmI810DMA dma; + drmBufPtr buf; + int retcode, i = 0; + + while (1) { + retcode = drmCommandWriteRead(imesa->driFd, DRM_I810_GETBUF, + &dma, sizeof(drmI810DMA)); + + if (dma.granted == 1 && retcode == 0) + break; + + if (++i > 1000) { + drmCommandNone(imesa->driFd, DRM_I810_FLUSH); + i = 0; + } + } + + buf = &(imesa->i810Screen->bufs->list[dma.request_idx]); + buf->idx = dma.request_idx; + buf->used = 0; + buf->total = dma.request_size; + buf->address = (drmAddress)dma.virtual; + + return buf; +} + + + +#define DEPTH_SCALE ((1<<16)-1) + +static void i810Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + drmI810Clear clear; + int i; + + clear.flags = 0; + clear.clear_color = imesa->ClearColor; + clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE); + + I810_FIREVERTICES( imesa ); + + if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) { + clear.flags |= I810_FRONT; + mask &= ~DD_FRONT_LEFT_BIT; + } + + if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) { + clear.flags |= I810_BACK; + mask &= ~DD_BACK_LEFT_BIT; + } + + if (mask & DD_DEPTH_BIT) { + if (ctx->Depth.Mask) + clear.flags |= I810_DEPTH; + mask &= ~DD_DEPTH_BIT; + } + + if (clear.flags) { + LOCK_HARDWARE( imesa ); + + /* flip top to bottom */ + cy = dPriv->h-cy-ch; + cx += imesa->drawX; + cy += imesa->drawY; + + for (i = 0 ; i < imesa->numClipRects ; ) + { + int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, imesa->numClipRects); + XF86DRIClipRectPtr box = imesa->pClipRects; + XF86DRIClipRectPtr b = 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++ = *(XF86DRIClipRectPtr)&box[i]; + n++; + } + } + + imesa->sarea->nbox = n; + drmCommandWrite(imesa->driFd, DRM_I810_CLEAR, + &clear, sizeof(drmI810Clear)); + } + + UNLOCK_HARDWARE( imesa ); + imesa->upload_cliprects = GL_TRUE; + } + + if (mask) + _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); +} + + + + +/* + * Copy the back buffer to the front buffer. + */ +void i810CopyBuffer( const __DRIdrawablePrivate *dPriv ) +{ + i810ContextPtr imesa; + XF86DRIClipRectPtr pbox; + int nbox, i, tmp; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate; + + I810_FIREVERTICES( imesa ); + LOCK_HARDWARE( imesa ); + + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + + for (i = 0 ; i < nbox ; ) + { + int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, dPriv->numClipRects); + XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)imesa->sarea->boxes; + + imesa->sarea->nbox = nr - i; + + for ( ; i < nr ; i++) + *b++ = pbox[i]; + + drmCommandNone(imesa->driFd, DRM_I810_SWAP); + } + + tmp = GET_ENQUEUE_AGE(imesa); + UNLOCK_HARDWARE( imesa ); + + /* multiarb will suck the life out of the server without this throttle: + */ + if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) { + i810WaitAge(imesa, imesa->lastSwap); + } + + imesa->lastSwap = tmp; + imesa->upload_cliprects = GL_TRUE; +} + + +/* + * XXX implement when full-screen extension is done. + */ +void i810PageFlip( const __DRIdrawablePrivate *dPriv ) +{ + i810ContextPtr imesa; + int tmp, ret; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + imesa = (i810ContextPtr) dPriv->driContextPriv->driverPrivate; + + I810_FIREVERTICES( imesa ); + LOCK_HARDWARE( imesa ); + + if (dPriv->pClipRects) { + *(XF86DRIClipRectRec *)imesa->sarea->boxes = dPriv->pClipRects[0]; + imesa->sarea->nbox = 1; + } + ret = drmCommandNone(imesa->driFd, DRM_I810_FLIP); + if (ret) { + fprintf(stderr, "%s: %d\n", __FUNCTION__, ret); + UNLOCK_HARDWARE( imesa ); + exit(1); + } + + tmp = GET_ENQUEUE_AGE(imesa); + UNLOCK_HARDWARE( imesa ); + + /* multiarb will suck the life out of the server without this throttle: + */ + if (GET_DISPATCH_AGE(imesa) < imesa->lastSwap) { + i810WaitAge(imesa, imesa->lastSwap); + } + + /* i810SetDrawBuffer( imesa->glCtx, imesa->glCtx->Color.DriverDrawBuffer );*/ + i810DrawBuffer( imesa->glCtx, imesa->glCtx->Color.DrawBuffer ); + imesa->upload_cliprects = GL_TRUE; + imesa->lastSwap = tmp; + return; +} + + +/* This waits for *everybody* to finish rendering -- overkill. + */ +void i810DmaFinish( i810ContextPtr imesa ) +{ + I810_FIREVERTICES( imesa ); + + LOCK_HARDWARE( imesa ); + i810RegetLockQuiescent( imesa ); + UNLOCK_HARDWARE( imesa ); +} + + +void i810RegetLockQuiescent( i810ContextPtr imesa ) +{ + drmUnlock(imesa->driFd, imesa->hHWContext); + i810GetLock( imesa, DRM_LOCK_QUIESCENT ); +} + +void i810WaitAgeLocked( i810ContextPtr imesa, int age ) +{ + int i = 0, j; + + while (++i < 5000) { + drmCommandNone(imesa->driFd, DRM_I810_GETAGE); + if (GET_DISPATCH_AGE(imesa) >= age) + return; + for (j = 0 ; j < 1000 ; j++) + ; + } + + drmCommandNone(imesa->driFd, DRM_I810_FLUSH); +} + + +void i810WaitAge( i810ContextPtr imesa, int age ) +{ + int i = 0, j; + + while (++i < 5000) { + drmCommandNone(imesa->driFd, DRM_I810_GETAGE); + if (GET_DISPATCH_AGE(imesa) >= age) + return; + for (j = 0 ; j < 1000 ; j++) + ; + } + + i = 0; + while (++i < 1000) { + drmCommandNone(imesa->driFd, DRM_I810_GETAGE); + if (GET_DISPATCH_AGE(imesa) >= age) + return; + usleep(1000); + } + + LOCK_HARDWARE(imesa); + drmCommandNone(imesa->driFd, DRM_I810_FLUSH); + UNLOCK_HARDWARE(imesa); +} + + + + +static int intersect_rect( XF86DRIClipRectPtr out, + XF86DRIClipRectPtr a, + XF86DRIClipRectPtr b ) +{ + *out = *a; + if (b->x1 > out->x1) out->x1 = b->x1; + if (b->x2 < out->x2) out->x2 = b->x2; + if (out->x1 >= out->x2) return 0; + + if (b->y1 > out->y1) out->y1 = b->y1; + if (b->y2 < out->y2) out->y2 = b->y2; + if (out->y1 >= out->y2) return 0; + return 1; +} + + +static void emit_state( i810ContextPtr imesa ) +{ + GLuint dirty = imesa->dirty; + I810SAREAPtr sarea = imesa->sarea; + + if (dirty & I810_UPLOAD_BUFFERS) { + memcpy( sarea->BufferState, imesa->BufferSetup, + sizeof(imesa->BufferSetup) ); + } + + if (dirty & I810_UPLOAD_CTX) { + memcpy( sarea->ContextState, imesa->Setup, + sizeof(imesa->Setup) ); + } + + if (dirty & I810_UPLOAD_TEX0) { + memcpy(sarea->TexState[0], + imesa->CurrentTexObj[0]->Setup, + sizeof(imesa->CurrentTexObj[0]->Setup)); + } + + if (dirty & I810_UPLOAD_TEX1) { + GLuint *setup = sarea->TexState[1]; + + memcpy( setup, + imesa->CurrentTexObj[1]->Setup, + sizeof(imesa->CurrentTexObj[1]->Setup)); + + /* Need this for the case where both units are bound to the same + * texobj. + */ + setup[I810_TEXREG_MI1] ^= (MI1_MAP_0 ^ MI1_MAP_1); + setup[I810_TEXREG_MLC] ^= (MLC_MAP_0 ^ MLC_MAP_1); + setup[I810_TEXREG_MLL] ^= (MLL_MAP_0 ^ MLL_MAP_1); + setup[I810_TEXREG_MCS] ^= (MCS_COORD_0 ^ MCS_COORD_1); + setup[I810_TEXREG_MF] ^= (MF_MAP_0 ^ MF_MAP_1); + } + + sarea->dirty = dirty; + imesa->dirty = 0; +} + + +static void age_imesa( i810ContextPtr imesa, int age ) +{ + if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->base.timestamp = age; + if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->base.timestamp = age; +} + + +void i810FlushPrimsLocked( i810ContextPtr imesa ) +{ + XF86DRIClipRectPtr pbox = (XF86DRIClipRectPtr)imesa->pClipRects; + int nbox = imesa->numClipRects; + drmBufPtr buffer = imesa->vertex_buffer; + I810SAREAPtr sarea = imesa->sarea; + drmI810Vertex vertex; + int i; + + if (I810_DEBUG & DEBUG_STATE) + i810PrintDirty( __FUNCTION__, imesa->dirty ); + + if (imesa->dirty) + emit_state( imesa ); + + vertex.idx = buffer->idx; + vertex.used = imesa->vertex_low; + vertex.discard = 0; + sarea->vertex_prim = imesa->hw_primitive; + + if (!nbox) { + vertex.used = 0; + } + else if (nbox > I810_NR_SAREA_CLIPRECTS) { + imesa->upload_cliprects = GL_TRUE; + } + + if (!nbox || !imesa->upload_cliprects) + { + if (nbox == 1) + sarea->nbox = 0; + else + sarea->nbox = nbox; + + vertex.discard = 1; + drmCommandWrite(imesa->driFd, DRM_I810_VERTEX, + &vertex, sizeof(drmI810Vertex)); + age_imesa(imesa, sarea->last_enqueue); + } + else + { + for (i = 0 ; i < nbox ; ) + { + int nr = MIN2(i + I810_NR_SAREA_CLIPRECTS, nbox); + XF86DRIClipRectPtr b = sarea->boxes; + + if (imesa->scissor) { + sarea->nbox = 0; + + for ( ; i < nr ; i++) { + b->x1 = pbox[i].x1 - imesa->drawX; + b->y1 = pbox[i].y1 - imesa->drawY; + b->x2 = pbox[i].x2 - imesa->drawX; + b->y2 = pbox[i].y2 - imesa->drawY; + + if (intersect_rect(b, b, &imesa->scissor_rect)) { + sarea->nbox++; + b++; + } + } + + /* Culled? + */ + if (!sarea->nbox) { + if (nr < nbox) continue; + vertex.used = 0; + } + } else { + sarea->nbox = nr - i; + for ( ; i < nr ; i++, b++) { + b->x1 = pbox[i].x1 - imesa->drawX; + b->y1 = pbox[i].y1 - imesa->drawY; + b->x2 = pbox[i].x2 - imesa->drawX; + b->y2 = pbox[i].y2 - imesa->drawY; + } + } + + /* Finished with the buffer? + */ + if (nr == nbox) + vertex.discard = 1; + + drmCommandWrite(imesa->driFd, DRM_I810_VERTEX, + &vertex, sizeof(drmI810Vertex)); + age_imesa(imesa, imesa->sarea->last_enqueue); + } + } + + /* Reset imesa vars: + */ + imesa->vertex_buffer = 0; + imesa->vertex_addr = 0; + imesa->vertex_low = 0; + imesa->vertex_high = 0; + imesa->vertex_last_prim = 0; + imesa->dirty = 0; + imesa->upload_cliprects = GL_FALSE; +} + +void i810FlushPrimsGetBuffer( i810ContextPtr imesa ) +{ + LOCK_HARDWARE(imesa); + + if (imesa->vertex_buffer) + i810FlushPrimsLocked( imesa ); + + imesa->vertex_buffer = i810_get_buffer_ioctl( imesa ); + imesa->vertex_high = imesa->vertex_buffer->total; + imesa->vertex_addr = (char *)imesa->vertex_buffer->address; + imesa->vertex_low = 4; /* leave room for instruction header */ + imesa->vertex_last_prim = imesa->vertex_low; + UNLOCK_HARDWARE(imesa); +} + + +void i810FlushPrims( i810ContextPtr imesa ) +{ + if (imesa->vertex_buffer) { + LOCK_HARDWARE( imesa ); + i810FlushPrimsLocked( imesa ); + UNLOCK_HARDWARE( imesa ); + } +} + + + +int i810_check_copy(int fd) +{ + return(drmCommandNone(fd, DRM_I810_DOCOPY)); +} + +static void i810Flush( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + I810_FIREVERTICES( imesa ); +} + +static void i810Finish( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + i810DmaFinish( imesa ); +} + +void i810InitIoctlFuncs( GLcontext *ctx ) +{ + ctx->Driver.Flush = i810Flush; + ctx->Driver.Clear = i810Clear; + ctx->Driver.Finish = i810Finish; +} diff --git a/src/mesa/drivers/dri/i810/i810ioctl.h b/src/mesa/drivers/dri/i810/i810ioctl.h new file mode 100644 index 00000000000..e287b57b19a --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810ioctl.h @@ -0,0 +1,49 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810ioctl.h,v 1.7 2002/10/30 12:51:33 alanh Exp $ */ + +#ifndef I810_IOCTL_H +#define I810_IOCTL_H + +#include "i810context.h" + +void i810EmitPrim( i810ContextPtr imesa ); +void i810FlushPrims( i810ContextPtr mmesa ); +void i810FlushPrimsLocked( i810ContextPtr mmesa ); +void i810FlushPrimsGetBuffer( i810ContextPtr imesa ); + +void i810WaitAgeLocked( i810ContextPtr imesa, int age ); +void i810WaitAge( i810ContextPtr imesa, int age ); +void i810DmaFinish( i810ContextPtr imesa ); +void i810RegetLockQuiescent( i810ContextPtr imesa ); +void i810InitIoctlFuncs( GLcontext *ctx ); +void i810CopyBuffer( const __DRIdrawablePrivate *dpriv ); +void i810PageFlip( const __DRIdrawablePrivate *dpriv ); +int i810_check_copy(int fd); + +#define I810_STATECHANGE(imesa, flag) \ +do { \ + if (imesa->vertex_low != imesa->vertex_last_prim) \ + i810FlushPrims(imesa); \ + imesa->dirty |= flag; \ +} while (0) \ + + +#define I810_FIREVERTICES(imesa) \ +do { \ + if (imesa->vertex_buffer) { \ + i810FlushPrims(imesa); \ + } \ +} while (0) + +static __inline GLuint *i810AllocDmaLow( i810ContextPtr imesa, int bytes ) +{ + if (imesa->vertex_low + bytes > imesa->vertex_high) + i810FlushPrimsGetBuffer( imesa ); + + { + GLuint *start = (GLuint *)(imesa->vertex_addr + imesa->vertex_low); + imesa->vertex_low += bytes; + return start; + } +} + +#endif diff --git a/src/mesa/drivers/dri/i810/i810render.c b/src/mesa/drivers/dri/i810/i810render.c new file mode 100644 index 00000000000..8d388d88b3f --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810render.c @@ -0,0 +1,214 @@ +/* + * 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 + */ + + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware acceleration where possible. + * + */ +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "imports.h" +#include "mtypes.h" + +#include "tnl/t_context.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810context.h" +#include "i810tris.h" +#include "i810state.h" +#include "i810vb.h" +#include "i810ioctl.h" + +/* + * Render unclipped vertex buffers by emitting vertices directly to + * dma buffers. Use strip/fan hardware primitives where possible. + * Try to simulate missing primitives with indexed vertices. + */ +#define HAVE_POINTS 0 +#define HAVE_LINES 1 +#define HAVE_LINE_STRIPS 1 +#define HAVE_TRIANGLES 1 +#define HAVE_TRI_STRIPS 1 +#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */ +#define HAVE_TRI_FANS 1 +#define HAVE_POLYGONS 1 +#define HAVE_QUADS 0 +#define HAVE_QUAD_STRIPS 0 + +#define HAVE_ELTS 0 + + +static GLuint hw_prim[GL_POLYGON+1] = { + 0, + PR_LINES, + 0, + PR_LINESTRIP, + PR_TRIANGLES, + PR_TRISTRIP_0, + PR_TRIFAN, + 0, + 0, + PR_POLYGON +}; + +static const GLenum reduced_prim[GL_POLYGON+1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + +/* Fallback to normal rendering. + */ +static void VERT_FALLBACK( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK ); + tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 ); + tnl->Driver.Render.PrimTabVerts[flags&PRIM_MODE_MASK]( ctx, start, + count, flags ); + I810_CONTEXT(ctx)->SetupNewInputs = VERT_BIT_CLIP; +} + + + +#define LOCAL_VARS i810ContextPtr imesa = I810_CONTEXT(ctx) +#define INIT( prim ) do { \ + I810_STATECHANGE(imesa, 0); \ + i810RasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] ); \ +} while (0) +#define NEW_PRIMITIVE() I810_STATECHANGE( imesa, 0 ) +#define NEW_BUFFER() I810_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() \ + (I810_DMA_BUF_SZ-4) / (imesa->vertex_size * 4) + + +#define EMIT_VERTS( ctx, j, nr ) \ + i810_emit_contiguous_verts(ctx, j, (j)+(nr)) + + +#define TAG(x) i810_##x +#include "tnl_dd/t_dd_dmatmp.h" + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + + +static GLboolean i810_run_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint i, length, flags = 0; + + /* Don't handle clipping or indexed vertices. + */ + if (VB->ClipOrMask || imesa->RenderIndex != 0 || VB->Elts) { + return GL_TRUE; + } + + imesa->SetupNewInputs = VERT_BIT_CLIP; + + tnl->Driver.Render.Start( ctx ); + + for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length) + { + flags = VB->Primitive[i]; + length= VB->PrimitiveLength[i]; + if (length) + i810_render_tab_verts[flags & PRIM_MODE_MASK]( ctx, i, i + length, + flags ); + } + + tnl->Driver.Render.Finish( ctx ); + + return GL_FALSE; /* finished the pipe */ +} + + +static void i810_check_render( GLcontext *ctx, struct gl_pipeline_stage *stage ) +{ + GLuint inputs = VERT_BIT_CLIP | VERT_BIT_COLOR0; + + if (ctx->RenderMode == GL_RENDER) { + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + inputs |= VERT_BIT_COLOR1; + + if (ctx->Texture.Unit[0]._ReallyEnabled) + inputs |= VERT_BIT_TEX0; + + if (ctx->Texture.Unit[1]._ReallyEnabled) + inputs |= VERT_BIT_TEX1; + + if (ctx->Fog.Enabled) + inputs |= VERT_BIT_FOG; + } + + stage->inputs = inputs; +} + + +static void dtr( struct gl_pipeline_stage *stage ) +{ + (void)stage; +} + + +const struct gl_pipeline_stage _i810_render_stage = +{ + "i810 render", + (_DD_NEW_SEPARATE_SPECULAR | + _NEW_TEXTURE| + _NEW_FOG| + _NEW_RENDERMODE), /* re-check (new inputs) */ + 0, /* re-run (always runs) */ + GL_TRUE, /* active */ + 0, 0, /* inputs (set in check_render), outputs */ + 0, 0, /* changed_inputs, private */ + dtr, /* destructor */ + i810_check_render, /* check - initially set to alloc data */ + i810_run_render /* run */ +}; diff --git a/src/mesa/drivers/dri/i810/i810screen.c b/src/mesa/drivers/dri/i810/i810screen.c new file mode 100644 index 00000000000..2c978e10a4e --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810screen.c @@ -0,0 +1,288 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810screen.c,v 1.2 2002/10/30 12:51:33 alanh Exp $ */ + +/* + * Authors: + * Keith Whitwell + * + */ + + +#include "glheader.h" +#include "context.h" +#include "matrix.h" +#include "simple_list.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810state.h" +#include "i810tex.h" +#include "i810span.h" +#include "i810tris.h" +#include "i810ioctl.h" + + + +/* static int i810_malloc_proxy_buf(drmBufMapPtr buffers) */ +/* { */ +/* char *buffer; */ +/* drmBufPtr buf; */ +/* int i; */ + +/* buffer = Xmalloc(I810_DMA_BUF_SZ); */ +/* if(buffer == NULL) return -1; */ +/* for(i = 0; i < I810_DMA_BUF_NR; i++) { */ +/* buf = &(buffers->list[i]); */ +/* buf->address = (drmAddress)buffer; */ +/* } */ +/* return 0; */ +/* } */ + +static drmBufMapPtr i810_create_empty_buffers(void) +{ + drmBufMapPtr retval; + + retval = (drmBufMapPtr)Xmalloc(sizeof(drmBufMap)); + if(retval == NULL) return NULL; + memset(retval, 0, sizeof(drmBufMap)); + retval->list = (drmBufPtr)Xmalloc(sizeof(drmBuf) * I810_DMA_BUF_NR); + if(retval->list == NULL) { + Xfree(retval); + return NULL; + } + memset(retval->list, 0, sizeof(drmBuf) * I810_DMA_BUF_NR); + return retval; +} + + +static GLboolean +i810InitDriver(__DRIscreenPrivate *sPriv) +{ + i810ScreenPrivate *i810Screen; + I810DRIPtr gDRIPriv = (I810DRIPtr)sPriv->pDevPriv; + + /* Check the DRI externsion version */ + if ( sPriv->driMajor != 4 || sPriv->driMinor < 0 ) { + __driUtilMessage( "i810 DRI driver expected DRI version 4.0.x " + "but got version %d.%d.%d", + sPriv->driMajor, sPriv->driMinor, sPriv->driPatch ); + return GL_FALSE; + } + + /* Check that the DDX driver version is compatible */ + if (sPriv->ddxMajor != 1 || + sPriv->ddxMinor < 0) { + __driUtilMessage("i810 DRI driver expected DDX driver version 1.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if (sPriv->drmMajor != 1 || + sPriv->drmMinor < 2) { + __driUtilMessage("i810 DRI driver expected DRM driver version 1.2.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + return GL_FALSE; + } + + /* Allocate the private area */ + i810Screen = (i810ScreenPrivate *)Xmalloc(sizeof(i810ScreenPrivate)); + if (!i810Screen) { + __driUtilMessage("i810InitDriver: alloc i810ScreenPrivate struct failed"); + return GL_FALSE; + } + + i810Screen->driScrnPriv = sPriv; + sPriv->private = (void *)i810Screen; + + i810Screen->deviceID=gDRIPriv->deviceID; + i810Screen->width=gDRIPriv->width; + i810Screen->height=gDRIPriv->height; + i810Screen->mem=gDRIPriv->mem; + i810Screen->cpp=gDRIPriv->cpp; + i810Screen->fbStride=gDRIPriv->fbStride; + i810Screen->fbOffset=gDRIPriv->fbOffset; + + if (gDRIPriv->bitsPerPixel == 15) + i810Screen->fbFormat = DV_PF_555; + else + i810Screen->fbFormat = DV_PF_565; + + i810Screen->backOffset=gDRIPriv->backOffset; + i810Screen->depthOffset=gDRIPriv->depthOffset; + i810Screen->backPitch = gDRIPriv->auxPitch; + i810Screen->backPitchBits = gDRIPriv->auxPitchBits; + i810Screen->textureOffset=gDRIPriv->textureOffset; + i810Screen->textureSize=gDRIPriv->textureSize; + i810Screen->logTextureGranularity = gDRIPriv->logTextureGranularity; + + i810Screen->bufs = i810_create_empty_buffers(); + if (i810Screen->bufs == NULL) { + __driUtilMessage("i810InitDriver: i810_create_empty_buffers() failed"); + Xfree(i810Screen); + return GL_FALSE; + } + + i810Screen->back.handle = gDRIPriv->backbuffer; + i810Screen->back.size = gDRIPriv->backbufferSize; + + if (drmMap(sPriv->fd, + i810Screen->back.handle, + i810Screen->back.size, + (drmAddress *)&i810Screen->back.map) != 0) { + Xfree(i810Screen); + sPriv->private = NULL; + __driUtilMessage("i810InitDriver: drmMap failed"); + return GL_FALSE; + } + + i810Screen->depth.handle = gDRIPriv->depthbuffer; + i810Screen->depth.size = gDRIPriv->depthbufferSize; + + if (drmMap(sPriv->fd, + i810Screen->depth.handle, + i810Screen->depth.size, + (drmAddress *)&i810Screen->depth.map) != 0) { + Xfree(i810Screen); + drmUnmap(i810Screen->back.map, i810Screen->back.size); + sPriv->private = NULL; + __driUtilMessage("i810InitDriver: drmMap (2) failed"); + return GL_FALSE; + } + + i810Screen->tex.handle = gDRIPriv->textures; + i810Screen->tex.size = gDRIPriv->textureSize; + + if (drmMap(sPriv->fd, + i810Screen->tex.handle, + i810Screen->tex.size, + (drmAddress *)&i810Screen->tex.map) != 0) { + Xfree(i810Screen); + drmUnmap(i810Screen->back.map, i810Screen->back.size); + drmUnmap(i810Screen->depth.map, i810Screen->depth.size); + sPriv->private = NULL; + __driUtilMessage("i810InitDriver: drmMap (3) failed"); + return GL_FALSE; + } + + i810Screen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + + return GL_TRUE; +} + +static void +i810DestroyScreen(__DRIscreenPrivate *sPriv) +{ + i810ScreenPrivate *i810Screen = (i810ScreenPrivate *)sPriv->private; + + /* Need to unmap all the bufs and maps here: + */ + drmUnmap(i810Screen->back.map, i810Screen->back.size); + drmUnmap(i810Screen->depth.map, i810Screen->depth.size); + drmUnmap(i810Screen->tex.map, i810Screen->tex.size); + + Xfree(i810Screen); + sPriv->private = NULL; +} + + +static GLboolean +i810CreateBuffer( __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap ) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + driDrawPriv->driverPrivate = (void *) + _mesa_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->stencilBits > 0, + mesaVis->accumRedBits > 0, + GL_FALSE /* s/w alpha planes */); + return (driDrawPriv->driverPrivate != NULL); + } +} + + +static void +i810DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + + +static GLboolean +i810OpenCloseFullScreen(__DRIcontextPrivate *driContextPriv) +{ + return GL_TRUE; +} + +static const struct __DriverAPIRec i810API = { + .InitDriver = i810InitDriver, + .DestroyScreen = i810DestroyScreen, + .CreateContext = i810CreateContext, + .DestroyContext = i810DestroyContext, + .CreateBuffer = i810CreateBuffer, + .DestroyBuffer = i810DestroyBuffer, + .SwapBuffers = i810SwapBuffers, + .MakeCurrent = i810MakeCurrent, + .UnbindContext = i810UnbindContext, + .OpenFullScreen = i810OpenCloseFullScreen, + .CloseFullScreen = i810OpenCloseFullScreen, + .GetSwapInfo = NULL, + .GetMSC = NULL, + .WaitForMSC = NULL, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL +}; + + +/* + * This is the bootstrap function for the driver. + * The __driCreateScreen name is the symbol that libGL.so fetches. + * Return: pointer to a __DRIscreenPrivate. + */ +#ifndef _SOLO +void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, + int numConfigs, __GLXvisualConfig *config) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &i810API); + return (void *) psp; +} +#else +void *__driCreateScreen(struct DRIDriverRec *driver, + struct DRIDriverContextRec *driverContext) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(driver, driverContext, &i810API); + return (void *) psp; +} +#endif diff --git a/src/mesa/drivers/dri/i810/i810screen.h b/src/mesa/drivers/dri/i810/i810screen.h new file mode 100644 index 00000000000..4625bc5e9f6 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810screen.h @@ -0,0 +1,99 @@ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * + */ + +#ifndef _I810_INIT_H_ +#define _I810_INIT_H_ + +#include +#include "dri_util.h" + +typedef struct { + drmHandle handle; + drmSize size; + char *map; +} i810Region, *i810RegionPtr; + +typedef struct { + i810Region front; + i810Region back; + i810Region depth; + i810Region tex; + + int deviceID; + int width; + int height; + int mem; + + int cpp; /* for front and back buffers */ + int bitsPerPixel; + + int fbFormat; + int fbOffset; + int fbStride; + + int backOffset; + int depthOffset; + + int backPitch; + int backPitchBits; + + int textureOffset; + int textureSize; + int logTextureGranularity; + + __DRIscreenPrivate *driScrnPriv; + drmBufMapPtr bufs; + unsigned int sarea_priv_offset; +} i810ScreenPrivate; + + +extern GLboolean +i810CreateContext( const __GLcontextModes *mesaVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ); + +extern void +i810DestroyContext(__DRIcontextPrivate *driContextPriv); + +extern GLboolean +i810UnbindContext(__DRIcontextPrivate *driContextPriv); + +extern GLboolean +i810MakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv); + +extern void +i810SwapBuffers(__DRIdrawablePrivate *driDrawPriv); + +#endif diff --git a/src/mesa/drivers/dri/i810/i810span.c b/src/mesa/drivers/dri/i810/i810span.c new file mode 100644 index 00000000000..dc8f4d1cb95 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810span.c @@ -0,0 +1,170 @@ +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "colormac.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810span.h" +#include "i810ioctl.h" +#include "swrast/swrast.h" + + +#define DBG 0 + +#define LOCAL_VARS \ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ + i810ScreenPrivate *i810Screen = imesa->i810Screen; \ + GLuint pitch = i810Screen->backPitch; \ + GLuint height = dPriv->h; \ + GLushort p; \ + char *buf = (char *)(imesa->drawMap + \ + dPriv->x * 2 + \ + dPriv->y * pitch); \ + char *read_buf = (char *)(imesa->readMap + \ + dPriv->x * 2 + \ + dPriv->y * pitch); \ + (void) read_buf; (void) buf; (void) p + +#define LOCAL_DEPTH_VARS \ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ + i810ScreenPrivate *i810Screen = imesa->i810Screen; \ + GLuint pitch = i810Screen->backPitch; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(i810Screen->depth.map + \ + dPriv->x * 2 + \ + dPriv->y * pitch) + +#define INIT_MONO_PIXEL(p, color) \ + p = PACK_COLOR_565( color[0], color[1], color[2] ) + +#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \ + _y >= miny && _y < maxy) + + +#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \ + if ( _y < miny || _y >= maxy ) { \ + _n1 = 0, _x1 = x; \ + } else { \ + _n1 = _n; \ + _x1 = _x; \ + if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \ + if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \ + } + +#define Y_FLIP(_y) (height - _y - 1) + +#define HW_LOCK() \ + i810ContextPtr imesa = I810_CONTEXT(ctx); \ + I810_FIREVERTICES(imesa); \ + i810DmaFinish(imesa); \ + LOCK_HARDWARE_QUIESCENT(imesa); + +#define HW_CLIPLOOP() \ + do { \ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; \ + int _nc = dPriv->numClipRects; \ + while (_nc--) { \ + int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \ + int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \ + int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \ + int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; + + +#define HW_ENDCLIPLOOP() \ + } \ + } while (0) + +#define HW_UNLOCK() \ + UNLOCK_HARDWARE(imesa); + + + + +/* 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 >> 8) & 0xf8) * 255 / 0xf8; \ + rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \ + rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \ + rgba[3] = 255; \ +} while(0) + +#define TAG(x) i810##x##_565 +#include "spantmp.h" + + + +/* 16 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + _x*2 + _y*pitch); + +#define TAG(x) i810##x##_16 +#include "depthtmp.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 i810SetBuffer(GLcontext *ctx, GLframebuffer *buffer, + GLuint bufferBit ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + (void) buffer; + + switch(bufferBit) { + case FRONT_LEFT_BIT: + if ( imesa->sarea->pf_current_page == 1) + imesa->readMap = imesa->i810Screen->back.map; + else + imesa->readMap = (char*)imesa->driScreen->pFB; + break; + case BACK_LEFT_BIT: + if ( imesa->sarea->pf_current_page == 1) + imesa->readMap = (char*)imesa->driScreen->pFB; + else + imesa->readMap = imesa->i810Screen->back.map; + break; + default: + ASSERT(0); + break; + } + imesa->drawMap = imesa->readMap; +} + + +void i810InitSpanFuncs( GLcontext *ctx ) +{ + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + + swdd->SetBuffer = i810SetBuffer; + + swdd->WriteRGBASpan = i810WriteRGBASpan_565; + swdd->WriteRGBSpan = i810WriteRGBSpan_565; + swdd->WriteMonoRGBASpan = i810WriteMonoRGBASpan_565; + swdd->WriteRGBAPixels = i810WriteRGBAPixels_565; + swdd->WriteMonoRGBAPixels = i810WriteMonoRGBAPixels_565; + swdd->ReadRGBASpan = i810ReadRGBASpan_565; + swdd->ReadRGBAPixels = i810ReadRGBAPixels_565; + + swdd->ReadDepthSpan = i810ReadDepthSpan_16; + swdd->WriteDepthSpan = i810WriteDepthSpan_16; + swdd->ReadDepthPixels = i810ReadDepthPixels_16; + swdd->WriteDepthPixels = i810WriteDepthPixels_16; +} diff --git a/src/mesa/drivers/dri/i810/i810span.h b/src/mesa/drivers/dri/i810/i810span.h new file mode 100644 index 00000000000..a7b809bf18b --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810span.h @@ -0,0 +1,6 @@ +#ifndef _I810_SPAN_H +#define _I810_SPAN_H + +extern void i810InitSpanFuncs( GLcontext *ctx ); + +#endif diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c new file mode 100644 index 00000000000..23432b2c072 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810state.c @@ -0,0 +1,1019 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810state.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */ + +#include + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" +#include "colormac.h" + +#include "texmem.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810context.h" +#include "i810state.h" +#include "i810tex.h" +#include "i810vb.h" +#include "i810tris.h" +#include "i810ioctl.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + +static __inline__ GLuint i810PackColor(GLuint format, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + + if (I810_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + switch (format) { + case DV_PF_555: + return PACK_COLOR_1555( a, r, g, b ); + case DV_PF_565: + return PACK_COLOR_565( r, g, b ); + default: + fprintf(stderr, "unknown format %d\n", (int)format); + return 0; + } +} + + +static void i810AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLuint a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF); + GLubyte refByte; + + CLAMPED_FLOAT_TO_UBYTE(refByte, ref); + + switch (ctx->Color.AlphaFunc) { + case GL_NEVER: a |= ZA_ALPHA_NEVER; break; + case GL_LESS: a |= ZA_ALPHA_LESS; break; + case GL_GEQUAL: a |= ZA_ALPHA_GEQUAL; break; + case GL_LEQUAL: a |= ZA_ALPHA_LEQUAL; break; + case GL_GREATER: a |= ZA_ALPHA_GREATER; break; + case GL_NOTEQUAL: a |= ZA_ALPHA_NOTEQUAL; break; + case GL_EQUAL: a |= ZA_ALPHA_EQUAL; break; + case GL_ALWAYS: a |= ZA_ALPHA_ALWAYS; break; + default: return; + } + + a |= ((refByte & 0xfc) << ZA_ALPHAREF_SHIFT); + + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_ZA] &= ~(ZA_ALPHA_MASK|ZA_ALPHAREF_MASK); + imesa->Setup[I810_CTXREG_ZA] |= a; +} + +static void i810BlendEquation(GLcontext *ctx, GLenum mode) +{ + /* Can only do GL_ADD equation in hardware */ + FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_BLEND_EQ, mode != GL_FUNC_ADD_EXT); + + /* BlendEquation sets ColorLogicOpEnabled in an unexpected + * manner. + */ + FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); +} + +static void i810BlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLuint a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND; + GLboolean fallback = GL_FALSE; + + switch (ctx->Color.BlendSrcRGB) { + case GL_ZERO: a |= SDM_SRC_ZERO; break; + case GL_SRC_ALPHA: a |= SDM_SRC_SRC_ALPHA; break; + case GL_ONE: a |= SDM_SRC_ONE; break; + case GL_DST_COLOR: a |= SDM_SRC_DST_COLOR; break; + case GL_ONE_MINUS_DST_COLOR: a |= SDM_SRC_INV_DST_COLOR; break; + case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_SRC_INV_SRC_ALPHA; break; + case GL_DST_ALPHA: a |= SDM_SRC_ONE; break; + case GL_ONE_MINUS_DST_ALPHA: a |= SDM_SRC_ZERO; break; + case GL_SRC_ALPHA_SATURATE: /*a |= SDM_SRC_SRC_ALPHA; break;*/ + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + fallback = GL_TRUE; + break; + default: + return; + } + + switch (ctx->Color.BlendDstRGB) { + case GL_SRC_ALPHA: a |= SDM_DST_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_DST_INV_SRC_ALPHA; break; + case GL_ZERO: a |= SDM_DST_ZERO; break; + case GL_ONE: a |= SDM_DST_ONE; break; + case GL_SRC_COLOR: a |= SDM_DST_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: a |= SDM_DST_INV_SRC_COLOR; break; + case GL_DST_ALPHA: a |= SDM_DST_ONE; break; + case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break; + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + fallback = GL_TRUE; + break; + default: + return; + } + + FALLBACK( imesa, I810_FALLBACK_BLEND_FUNC, fallback); + if (!fallback) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_SDM] &= ~(SDM_SRC_MASK|SDM_DST_MASK); + imesa->Setup[I810_CTXREG_SDM] |= a; + } +} + + +/* Shouldn't be called as the extension is disabled. + */ +static void i810BlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, + GLenum dfactorA ) +{ + if (dfactorRGB != dfactorA || sfactorRGB != sfactorA) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glBlendEquation (disabled)"); + } + + i810BlendFunc( ctx, sfactorRGB, dfactorRGB ); +} + + + +static void i810DepthFunc(GLcontext *ctx, GLenum func) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + int zmode; + + switch(func) { + case GL_NEVER: zmode = LCS_Z_NEVER; break; + case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break; + case GL_LESS: zmode = LCS_Z_LESS; break; + case GL_LEQUAL: zmode = LCS_Z_LEQUAL; break; + case GL_EQUAL: zmode = LCS_Z_EQUAL; break; + case GL_GREATER: zmode = LCS_Z_GREATER; break; + case GL_GEQUAL: zmode = LCS_Z_GEQUAL; break; + case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break; + default: return; + } + + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK; + imesa->Setup[I810_CTXREG_LCS] |= zmode; +} + +static void i810DepthMask(GLcontext *ctx, GLboolean flag) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + + if (flag) + imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE; + else + imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE; +} + + +/* ============================================================= + * Polygon stipple + * + * The i810 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + */ +static void i810PolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + const GLubyte *m = mask; + GLubyte p[4]; + int i,j,k; + int active = (ctx->Polygon.StippleFlag && + imesa->reduced_primitive == GL_TRIANGLES); + GLuint newMask; + + if (active) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; + } + + p[0] = mask[12] & 0xf; p[0] |= p[0] << 4; + p[1] = mask[8] & 0xf; p[1] |= p[1] << 4; + p[2] = mask[4] & 0xf; p[2] |= p[2] << 4; + p[3] = mask[0] & 0xf; p[3] |= p[3] << 4; + + for (k = 0 ; k < 8 ; k++) + for (j = 0 ; j < 4; j++) + for (i = 0 ; i < 4 ; i++) + if (*m++ != p[j]) { + imesa->stipple_in_hw = 0; + return; + } + + newMask = ((p[0] & 0xf) << 0) | + ((p[1] & 0xf) << 4) | + ((p[2] & 0xf) << 8) | + ((p[3] & 0xf) << 12); + + if (newMask == 0xffff) { + /* this is needed to make conform pass */ + imesa->stipple_in_hw = 0; + return; + } + + imesa->Setup[I810_CTXREG_ST1] &= ~0xffff; + imesa->Setup[I810_CTXREG_ST1] |= newMask; + imesa->stipple_in_hw = 1; + + if (active) + imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; +} + + + +/* ============================================================= + * Hardware clipping + */ + + +static void i810Scissor( GLcontext *ctx, GLint x, GLint y, + GLsizei w, GLsizei h ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + + if (ctx->Scissor.Enabled) { + I810_FIREVERTICES(imesa); /* don't pipeline cliprect changes */ + imesa->upload_cliprects = GL_TRUE; + } + + imesa->scissor_rect.x1 = x; + imesa->scissor_rect.y1 = imesa->driDrawable->h - (y + h); + imesa->scissor_rect.x2 = x + w; + imesa->scissor_rect.y2 = imesa->driDrawable->h - y; +} + + +static void i810LogicOp( GLcontext *ctx, GLenum opcode ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + FALLBACK( imesa, I810_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) ); +} + +/* Fallback to swrast for select and feedback. + */ +static void i810RenderMode( GLcontext *ctx, GLenum mode ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + FALLBACK( imesa, I810_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); +} + + +void i810DrawBuffer(GLcontext *ctx, GLenum mode ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + int front = 0; + + /* + * _DrawDestMask is easier to cope with than . + */ + switch ( ctx->Color._DrawDestMask ) { + case FRONT_LEFT_BIT: + front=1; + break; + case BACK_LEFT_BIT: + front = 0; + break; + default: + /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ + FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + + if ( imesa->sarea->pf_current_page == 1 ) + front ^= 1; + + FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_FALSE ); + I810_FIREVERTICES(imesa); + I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS); + + if (front) + { + imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset | + imesa->i810Screen->backPitchBits); + i810XMesaSetFrontClipRects( imesa ); + } + else + { + imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset | + imesa->i810Screen->backPitchBits); + i810XMesaSetBackClipRects( imesa ); + } + + /* We want to update the s/w rast state too so that r200SetBuffer() + * gets called. + */ + _swrast_DrawBuffer(ctx, mode); +} + + +static void i810ReadBuffer(GLcontext *ctx, GLenum mode ) +{ + /* XXX anything? */ +} + + +static void i810ClearColor(GLcontext *ctx, const GLfloat color[4] ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLubyte c[4]; + CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); + imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat, + c[0], c[1], c[2], c[3] ); +} + + +/* ============================================================= + * Culling - the i810 isn't quite as clean here as the rest of + * its interfaces, but it's not bad. + */ +static void i810CullFaceFrontFace(GLcontext *ctx, GLenum unused) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLuint mode = LCS_CULL_BOTH; + + if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { + mode = LCS_CULL_CW; + if (ctx->Polygon.CullFaceMode == GL_FRONT) + mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW); + if (ctx->Polygon.FrontFace != GL_CCW) + mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW); + } + + imesa->LcsCullMode = mode; + + if (ctx->Polygon.CullFlag) + { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK; + imesa->Setup[I810_CTXREG_LCS] |= mode; + } +} + + +static void i810LineWidth( GLcontext *ctx, GLfloat widthf ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + int width = (int)ctx->Line._Width; + + imesa->LcsLineWidth = 0; + if (width & 1) imesa->LcsLineWidth |= LCS_LINEWIDTH_1_0; + if (width & 2) imesa->LcsLineWidth |= LCS_LINEWIDTH_2_0; + + if (imesa->reduced_primitive == GL_LINES) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0; + imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsLineWidth; + } +} + +static void i810PointSize( GLcontext *ctx, GLfloat sz ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + int size = (int)ctx->Point._Size; + + imesa->LcsPointSize = 0; + if (size & 1) imesa->LcsPointSize |= LCS_LINEWIDTH_1_0; + if (size & 2) imesa->LcsPointSize |= LCS_LINEWIDTH_2_0; + + if (imesa->reduced_primitive == GL_POINTS) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0; + imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsPointSize; + } +} + +/* ============================================================= + * Color masks + */ + +static void i810ColorMask(GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLuint tmp = 0; + + if (r && g && b) { + tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE; + FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE ); + } else if (!r && !g && !b) { + tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE; + FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE ); + } else { + FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_TRUE ); + return; + } + + if (tmp != imesa->Setup[I810_CTXREG_B2]) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_B2] = tmp; + imesa->dirty |= I810_UPLOAD_CTX; + } +} + +/* Seperate specular not fully implemented on the i810. + */ +static void i810LightModelfv(GLcontext *ctx, GLenum pname, + const GLfloat *param) +{ + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) + { + i810ContextPtr imesa = I810_CONTEXT( ctx ); + FALLBACK( imesa, I810_FALLBACK_SPECULAR, + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)); + } +} + +/* But the 815 has it... + */ +static void i810LightModelfv_i815(GLcontext *ctx, GLenum pname, + const GLfloat *param) +{ + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) + { + i810ContextPtr imesa = I810_CONTEXT( ctx ); + + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + imesa->Setup[I810_CTXREG_B1] |= B1_SPEC_ENABLE; + else + imesa->Setup[I810_CTXREG_B1] &= ~B1_SPEC_ENABLE; + } +} + +/* In Mesa 3.5 we can reliably do native flatshading. + */ +static void i810ShadeModel(GLcontext *ctx, GLenum mode) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + if (mode == GL_FLAT) + imesa->Setup[I810_CTXREG_LCS] |= LCS_INTERP_FLAT; + else + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_INTERP_FLAT; +} + + + +/* ============================================================= + * Fog + */ +static void i810Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + + if (pname == GL_FOG_COLOR) { + GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) | + ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) | + ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0)); + + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_FOG] = ((GFX_OP_FOG_COLOR | color) & + ~FOG_RESERVED_MASK); + } +} + + +/* ============================================================= + */ +static void i810Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + + switch(cap) { + case GL_ALPHA_TEST: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_B1] &= ~B1_ALPHA_TEST_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_B1] |= B1_ALPHA_TEST_ENABLE; + break; + case GL_BLEND: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_B1] &= ~B1_BLEND_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_B1] |= B1_BLEND_ENABLE; + + /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled. + */ + FALLBACK( imesa, I810_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); + break; + case GL_DEPTH_TEST: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_B1] &= ~B1_Z_TEST_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_B1] |= B1_Z_TEST_ENABLE; + break; + case GL_SCISSOR_TEST: + /* XXX without these next two lines, conform's scissor test fails */ + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS); + I810_FIREVERTICES(imesa); /* don't pipeline cliprect changes */ + imesa->upload_cliprects = GL_TRUE; + imesa->scissor = state; + break; + case GL_POLYGON_STIPPLE: + if (imesa->stipple_in_hw && imesa->reduced_primitive == GL_TRIANGLES) + { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; + } + break; + case GL_LINE_SMOOTH: + /* Need to fatten the lines by .5, or they disappear... + */ + if (imesa->reduced_primitive == GL_LINES) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5; + if (state) { + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5; + } + } + break; + case GL_POINT_SMOOTH: + if (imesa->reduced_primitive == GL_POINTS) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5; + if (state) { + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5; + } + } + break; + case GL_POLYGON_SMOOTH: + if (imesa->reduced_primitive == GL_TRIANGLES) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + } + break; + case GL_FOG: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_B1] &= ~B1_FOG_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_B1] |= B1_FOG_ENABLE; + break; + case GL_CULL_FACE: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK; + if (state) + imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode; + else + imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE; + break; + case GL_TEXTURE_2D: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + if (ctx->Texture.CurrentUnit == 0) { + imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE; + } else { + imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE; + } + break; + case GL_COLOR_LOGIC_OP: + FALLBACK( imesa, I810_FALLBACK_LOGICOP, + (state && ctx->Color.LogicOp != GL_COPY)); + break; + case GL_STENCIL_TEST: + FALLBACK( imesa, I810_FALLBACK_STENCIL, state ); + break; + default: + ; + } +} + + + + + + + +/* ============================================================= + */ + + + + +void i810EmitDrawingRectangle( i810ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + i810ScreenPrivate *i810Screen = imesa->i810Screen; + int x0 = imesa->drawX; + int y0 = imesa->drawY; + int x1 = x0 + dPriv->w; + int y1 = y0 + dPriv->h; + GLuint dr2, dr3, dr4; + + + /* Coordinate origin of the window - may be offscreen. + */ + dr4 = imesa->BufferSetup[I810_DESTREG_DR4] = ((y0<<16) | + (((unsigned)x0)&0xFFFF)); + + /* Clip to screen. + */ + if (x0 < 0) x0 = 0; + if (y0 < 0) y0 = 0; + if (x1 > i810Screen->width-1) x1 = i810Screen->width-1; + if (y1 > i810Screen->height-1) y1 = i810Screen->height-1; + + + /* Onscreen drawing rectangle. + */ + dr2 = imesa->BufferSetup[I810_DESTREG_DR2] = ((y0<<16) | x0); + dr3 = imesa->BufferSetup[I810_DESTREG_DR3] = (((y1+1)<<16) | (x1+1)); + + + imesa->dirty |= I810_UPLOAD_BUFFERS; +} + + + +static void i810CalcViewport( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = imesa->ViewportMatrix.m; + + /* See also i810_translate_vertex. SUBPIXEL adjustments can be done + * via state vars, too. + */ + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + m[MAT_SY] = - v[MAT_SY]; + m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + SUBPIXEL_Y; + m[MAT_SZ] = v[MAT_SZ] * (1.0 / 0xffff); + m[MAT_TZ] = v[MAT_TZ] * (1.0 / 0xffff); +} + +static void i810Viewport( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + i810CalcViewport( ctx ); +} + +static void i810DepthRange( GLcontext *ctx, + GLclampd nearval, GLclampd farval ) +{ + i810CalcViewport( ctx ); +} + + + +void i810PrintDirty( const char *msg, GLuint state ) +{ + fprintf(stderr, "%s (0x%x): %s%s%s%s\n", + msg, + (unsigned int) state, + (state & I810_UPLOAD_TEX0) ? "upload-tex0, " : "", + (state & I810_UPLOAD_TEX1) ? "upload-tex1, " : "", + (state & I810_UPLOAD_CTX) ? "upload-ctx, " : "", + (state & I810_UPLOAD_BUFFERS) ? "upload-bufs, " : "" + ); +} + + + +void i810InitState( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + i810ScreenPrivate *i810Screen = imesa->i810Screen; + + memset(imesa->Setup, 0, sizeof(imesa->Setup)); + + imesa->Setup[I810_CTXREG_VF] = 0; + + imesa->Setup[I810_CTXREG_MT] = (GFX_OP_MAP_TEXELS | + MT_UPDATE_TEXEL1_STATE | + MT_TEXEL1_COORD1 | + MT_TEXEL1_MAP1 | + MT_TEXEL1_DISABLE | + MT_UPDATE_TEXEL0_STATE | + MT_TEXEL0_COORD0 | + MT_TEXEL0_MAP0 | + MT_TEXEL0_DISABLE); + + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ITERATED_COLOR | + MC_ARG1_DONT_REPLICATE_ALPHA | + MC_ARG1_DONT_INVERT | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_ARG2_DONT_REPLICATE_ALPHA | + MC_ARG2_DONT_INVERT | + MC_UPDATE_OP | + MC_OP_ARG1 ); + + imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ONE | + MC_ARG1_DONT_REPLICATE_ALPHA | + MC_ARG1_DONT_INVERT | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_ARG2_DONT_REPLICATE_ALPHA | + MC_ARG2_DONT_INVERT | + MC_UPDATE_OP | + MC_OP_DISABLE ); + + + imesa->Setup[I810_CTXREG_MC2] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_2 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_CURRENT_COLOR | + MC_ARG1_REPLICATE_ALPHA | + MC_ARG1_DONT_INVERT | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_ARG2_DONT_REPLICATE_ALPHA | + MC_ARG2_DONT_INVERT | + MC_UPDATE_OP | + MC_OP_DISABLE ); + + + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_ARG1_DONT_INVERT | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_ARG2_DONT_INVERT | + MA_UPDATE_OP | + MA_OP_ARG1 ); + + + imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_ARG1_DONT_INVERT | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_ARG2_DONT_INVERT | + MA_UPDATE_OP | + MA_OP_ARG1 ); + + + imesa->Setup[I810_CTXREG_MA2] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_2 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_ARG1_DONT_INVERT | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_ARG2_DONT_INVERT | + MA_UPDATE_OP | + MA_OP_ARG1 ); + + + imesa->Setup[I810_CTXREG_SDM] = ( GFX_OP_SRC_DEST_MONO | + SDM_UPDATE_MONO_ENABLE | + 0 | + SDM_UPDATE_SRC_BLEND | + SDM_SRC_ONE | + SDM_UPDATE_DST_BLEND | + SDM_DST_ZERO ); + + /* Use for colormask: + */ + imesa->Setup[I810_CTXREG_CF0] = GFX_OP_COLOR_FACTOR; + imesa->Setup[I810_CTXREG_CF1] = 0xffffffff; + + imesa->Setup[I810_CTXREG_ZA] = (GFX_OP_ZBIAS_ALPHAFUNC | + ZA_UPDATE_ALPHAFUNC | + ZA_ALPHA_ALWAYS | + ZA_UPDATE_ZBIAS | + 0 | + ZA_UPDATE_ALPHAREF | + 0x0); + + imesa->Setup[I810_CTXREG_FOG] = (GFX_OP_FOG_COLOR | + (0xffffff & ~FOG_RESERVED_MASK)); + + /* Choose a pipe + */ + imesa->Setup[I810_CTXREG_B1] = ( GFX_OP_BOOL_1 | + B1_UPDATE_SPEC_SETUP_ENABLE | + 0 | + B1_UPDATE_ALPHA_SETUP_ENABLE | + B1_ALPHA_SETUP_ENABLE | + B1_UPDATE_CI_KEY_ENABLE | + 0 | + B1_UPDATE_CHROMAKEY_ENABLE | + 0 | + B1_UPDATE_Z_BIAS_ENABLE | + 0 | + B1_UPDATE_SPEC_ENABLE | + 0 | + B1_UPDATE_FOG_ENABLE | + 0 | + B1_UPDATE_ALPHA_TEST_ENABLE | + 0 | + B1_UPDATE_BLEND_ENABLE | + 0 | + B1_UPDATE_Z_TEST_ENABLE | + 0 ); + + imesa->Setup[I810_CTXREG_B2] = ( GFX_OP_BOOL_2 | + B2_UPDATE_MAP_CACHE_ENABLE | + B2_MAP_CACHE_ENABLE | + B2_UPDATE_ALPHA_DITHER_ENABLE | + 0 | + B2_UPDATE_FOG_DITHER_ENABLE | + 0 | + B2_UPDATE_SPEC_DITHER_ENABLE | + 0 | + B2_UPDATE_RGB_DITHER_ENABLE | + B2_RGB_DITHER_ENABLE | + B2_UPDATE_FB_WRITE_ENABLE | + B2_FB_WRITE_ENABLE | + B2_UPDATE_ZB_WRITE_ENABLE | + B2_ZB_WRITE_ENABLE ); + + imesa->Setup[I810_CTXREG_LCS] = ( GFX_OP_LINEWIDTH_CULL_SHADE_MODE | + LCS_UPDATE_ZMODE | + LCS_Z_LESS | + LCS_UPDATE_LINEWIDTH | + LCS_LINEWIDTH_1_0 | + LCS_UPDATE_ALPHA_INTERP | + LCS_ALPHA_INTERP | + LCS_UPDATE_FOG_INTERP | + 0 | + LCS_UPDATE_SPEC_INTERP | + 0 | + LCS_UPDATE_RGB_INTERP | + LCS_RGB_INTERP | + LCS_UPDATE_CULL_MODE | + LCS_CULL_DISABLE); + + imesa->LcsCullMode = LCS_CULL_CW; + imesa->LcsLineWidth = LCS_LINEWIDTH_1_0; + imesa->LcsPointSize = LCS_LINEWIDTH_1_0; + + imesa->Setup[I810_CTXREG_PV] = ( GFX_OP_PV_RULE | + PV_UPDATE_PIXRULE | + PV_PIXRULE_ENABLE | + PV_UPDATE_LINELIST | + PV_LINELIST_PV1 | + PV_UPDATE_TRIFAN | + PV_TRIFAN_PV2 | + PV_UPDATE_TRISTRIP | + PV_TRISTRIP_PV2 ); + + + imesa->Setup[I810_CTXREG_ST0] = GFX_OP_STIPPLE; + imesa->Setup[I810_CTXREG_ST1] = 0; + + imesa->Setup[I810_CTXREG_AA] = ( GFX_OP_ANTIALIAS | + AA_UPDATE_EDGEFLAG | + 0 | + AA_UPDATE_POLYWIDTH | + AA_POLYWIDTH_05 | + AA_UPDATE_LINEWIDTH | + AA_LINEWIDTH_05 | + AA_UPDATE_BB_EXPANSION | + 0 | + AA_UPDATE_AA_ENABLE | + 0 ); + + memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup)); + imesa->BufferSetup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO; + + if (imesa->glCtx->Visual.doubleBufferMode && imesa->sarea->pf_current_page == 0) { + /* use back buffer by default */ + imesa->drawMap = i810Screen->back.map; + imesa->readMap = i810Screen->back.map; + imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->backOffset | + i810Screen->backPitchBits); + } else { + /* use front buffer by default */ + imesa->drawMap = (char *)imesa->driScreen->pFB; + imesa->readMap = (char *)imesa->driScreen->pFB; + imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->fbOffset | + i810Screen->backPitchBits); + } + + imesa->BufferSetup[I810_DESTREG_DV0] = GFX_OP_DESTBUFFER_VARS; + imesa->BufferSetup[I810_DESTREG_DV1] = (DV_HORG_BIAS_OGL | + DV_VORG_BIAS_OGL | + i810Screen->fbFormat); + + imesa->BufferSetup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO; + imesa->BufferSetup[I810_DESTREG_DR1] = DR1_RECT_CLIP_ENABLE; +} + + +static void i810InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + I810_CONTEXT(ctx)->new_state |= new_state; +} + + +void i810InitStateFuncs(GLcontext *ctx) +{ + /* Callbacks for internal Mesa events. + */ + ctx->Driver.UpdateState = i810InvalidateState; + + /* API callbacks + */ + ctx->Driver.AlphaFunc = i810AlphaFunc; + ctx->Driver.BlendEquation = i810BlendEquation; + ctx->Driver.BlendFunc = i810BlendFunc; + ctx->Driver.BlendFuncSeparate = i810BlendFuncSeparate; + ctx->Driver.ClearColor = i810ClearColor; + ctx->Driver.ColorMask = i810ColorMask; + ctx->Driver.CullFace = i810CullFaceFrontFace; + ctx->Driver.DepthFunc = i810DepthFunc; + ctx->Driver.DepthMask = i810DepthMask; + ctx->Driver.Enable = i810Enable; + ctx->Driver.Fogfv = i810Fogfv; + ctx->Driver.FrontFace = i810CullFaceFrontFace; + ctx->Driver.LineWidth = i810LineWidth; + ctx->Driver.LogicOpcode = i810LogicOp; + ctx->Driver.PolygonStipple = i810PolygonStipple; + ctx->Driver.RenderMode = i810RenderMode; + ctx->Driver.Scissor = i810Scissor; + ctx->Driver.DrawBuffer = i810DrawBuffer; + ctx->Driver.ReadBuffer = i810ReadBuffer; + ctx->Driver.ShadeModel = i810ShadeModel; + ctx->Driver.DepthRange = i810DepthRange; + ctx->Driver.Viewport = i810Viewport; + ctx->Driver.PointSize = i810PointSize; + + if (IS_I815(I810_CONTEXT(ctx))) { + ctx->Driver.LightModelfv = i810LightModelfv_i815; + } else { + ctx->Driver.LightModelfv = i810LightModelfv; + } + + /* Pixel path fallbacks. + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + + /* Swrast hooks for imaging extensions: + */ + ctx->Driver.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; +} diff --git a/src/mesa/drivers/dri/i810/i810state.h b/src/mesa/drivers/dri/i810/i810state.h new file mode 100644 index 00000000000..118b075491b --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810state.h @@ -0,0 +1,15 @@ +#ifndef _I810_STATE_H +#define _I810_STATE_H + +#include "i810context.h" + +extern void i810InitState( GLcontext *ctx ); +extern void i810InitStateFuncs( GLcontext *ctx ); +extern void i810PrintDirty( const char *msg, GLuint state ); +extern void i810DrawBuffer(GLcontext *ctx, GLenum mode ); + +extern void i810Fallback( i810ContextPtr imesa, GLuint bit, GLboolean mode ); +#define FALLBACK( imesa, bit, mode ) i810Fallback( imesa, bit, mode ) + + +#endif diff --git a/src/mesa/drivers/dri/i810/i810tex.c b/src/mesa/drivers/dri/i810/i810tex.c new file mode 100644 index 00000000000..f2ebd35c9ac --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810tex.c @@ -0,0 +1,544 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tex.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */ + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "simple_list.h" +#include "enums.h" +#include "texstore.h" +#include "texformat.h" +#include "teximage.h" +#include "texmem.h" +#include "swrast/swrast.h" +#include "colormac.h" + +#include "mm.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810context.h" +#include "i810tex.h" +#include "i810state.h" +#include "i810ioctl.h" + + +/* + * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias. + */ +static GLuint i810ComputeLodBias(GLfloat bias) +{ + int b = (int) (bias * 16.0) + 12; + if (b > 63) + b = 63; + else if (b < -64) + b = -64; + return (GLuint) (b & MLC_LOD_BIAS_MASK); +} + + +static void i810SetTexWrapping(i810TextureObjectPtr tex, + GLenum swrap, GLenum twrap) +{ + tex->Setup[I810_TEXREG_MCS] &= ~(MCS_U_STATE_MASK| MCS_V_STATE_MASK); + + switch( swrap ) { + case GL_REPEAT: + tex->Setup[I810_TEXREG_MCS] |= MCS_U_WRAP; + break; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + tex->Setup[I810_TEXREG_MCS] |= MCS_U_CLAMP; + break; + case GL_MIRRORED_REPEAT: + tex->Setup[I810_TEXREG_MCS] |= MCS_U_MIRROR; + break; + default: + _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__); + } + + switch( twrap ) { + case GL_REPEAT: + tex->Setup[I810_TEXREG_MCS] |= MCS_V_WRAP; + break; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + tex->Setup[I810_TEXREG_MCS] |= MCS_V_CLAMP; + break; + case GL_MIRRORED_REPEAT: + tex->Setup[I810_TEXREG_MCS] |= MCS_V_MIRROR; + break; + default: + _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__); + } +} + + +static void i810SetTexFilter(i810ContextPtr imesa, + i810TextureObjectPtr t, + GLenum minf, GLenum magf, + GLfloat bias) +{ + t->Setup[I810_TEXREG_MF] &= ~(MF_MIN_MASK| + MF_MAG_MASK| + MF_MIP_MASK); + t->Setup[I810_TEXREG_MLC] &= ~(MLC_LOD_BIAS_MASK); + + switch (minf) { + case GL_NEAREST: + t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_NONE; + break; + case GL_LINEAR: + t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_NEAREST; + if (magf == GL_LINEAR) { + /*bias -= 0.5;*/ /* this doesn't work too good */ + } + break; + case GL_LINEAR_MIPMAP_NEAREST: + t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + if (IS_I815(imesa)) + t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_LINEAR; + else + t->Setup[I810_TEXREG_MF] |= MF_MIN_NEAREST | MF_MIP_DITHER; + /* + if (magf == GL_LINEAR) { + bias -= 0.5; + } + */ + bias -= 0.5; /* always biasing here looks better */ + break; + case GL_LINEAR_MIPMAP_LINEAR: + if (IS_I815(imesa)) + t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_LINEAR; + else + t->Setup[I810_TEXREG_MF] |= MF_MIN_LINEAR | MF_MIP_DITHER; + break; + default: + return; + } + + switch (magf) { + case GL_NEAREST: + t->Setup[I810_TEXREG_MF] |= MF_MAG_NEAREST; + break; + case GL_LINEAR: + t->Setup[I810_TEXREG_MF] |= MF_MAG_LINEAR; + break; + default: + return; + } + + t->Setup[I810_TEXREG_MLC] |= i810ComputeLodBias(bias); +} + + +static void i810SetTexBorderColor(i810TextureObjectPtr t, + GLubyte color[4]) +{ + /* Need a fallback. + */ +} +static i810TextureObjectPtr i810AllocTexObj( GLcontext *ctx, struct gl_texture_object *texObj ) +{ + i810TextureObjectPtr t; + i810ContextPtr imesa = I810_CONTEXT(ctx); + + t = CALLOC_STRUCT( i810_texture_object_t ); + texObj->DriverData = t; + if ( t != NULL ) { + GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias; + /* Initialize non-image-dependent parts of the state: + */ + t->base.tObj = texObj; + t->Setup[I810_TEXREG_MI0] = GFX_OP_MAP_INFO; + t->Setup[I810_TEXREG_MI1] = MI1_MAP_0; + t->Setup[I810_TEXREG_MI2] = MI2_DIMENSIONS_ARE_LOG2; + t->Setup[I810_TEXREG_MLC] = (GFX_OP_MAP_LOD_CTL | + MLC_MAP_0 | + /*MLC_DITHER_WEIGHT_FULL |*/ + MLC_DITHER_WEIGHT_12 | + MLC_UPDATE_LOD_BIAS | + 0x0); + t->Setup[I810_TEXREG_MCS] = (GFX_OP_MAP_COORD_SETS | + MCS_COORD_0 | + MCS_UPDATE_NORMALIZED | + MCS_NORMALIZED_COORDS | + MCS_UPDATE_V_STATE | + MCS_V_WRAP | + MCS_UPDATE_U_STATE | + MCS_U_WRAP); + t->Setup[I810_TEXREG_MF] = (GFX_OP_MAP_FILTER | + MF_MAP_0 | + MF_UPDATE_ANISOTROPIC | + MF_UPDATE_MIP_FILTER | + MF_UPDATE_MAG_FILTER | + MF_UPDATE_MIN_FILTER); + + make_empty_list( & t->base ); + + i810SetTexWrapping( t, texObj->WrapS, texObj->WrapT ); + /*i830SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );*/ + i810SetTexFilter( imesa, t, texObj->MinFilter, texObj->MagFilter, bias ); + i810SetTexBorderColor( t, texObj->_BorderChan ); + } + + return t; +} + + +static void i810TexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData; + if (!t) + return; + + if ( target != GL_TEXTURE_2D ) + return; + + /* Can't do the update now as we don't know whether to flush + * vertices or not. Setting imesa->new_state means that + * i810UpdateTextureState() will be called before any triangles are + * rendered. If a statechange has occurred, it will be detected at + * that point, and buffered vertices flushed. + */ + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + { + GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias; + i810SetTexFilter( imesa, t, tObj->MinFilter, tObj->MagFilter, bias ); + } + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + i810SetTexWrapping( t, tObj->WrapS, tObj->WrapT ); + break; + + case GL_TEXTURE_BORDER_COLOR: + i810SetTexBorderColor( t, tObj->_BorderChan ); + break; + + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + /* This isn't the most efficient solution but there doesn't appear to + * be a nice alternative for Radeon. Since there's no LOD clamping, + * we just have to rely on loading the right subset of mipmap levels + * to simulate a clamped LOD. + */ + I810_FIREVERTICES( I810_CONTEXT(ctx) ); + driSwapOutTextureObject( (driTextureObject *) t ); + break; + + default: + return; + } + + if (t == imesa->CurrentTexObj[0]) { + I810_STATECHANGE( imesa, I810_UPLOAD_TEX0 ); + } + + if (t == imesa->CurrentTexObj[1]) { + I810_STATECHANGE( imesa, I810_UPLOAD_TEX1 ); + } +} + + +static void i810TexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) +{ + i810ContextPtr imesa = I810_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: { + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLfloat *fc = texUnit->EnvColor; + GLuint r, g, b, a, col; + CLAMPED_FLOAT_TO_UBYTE(r, fc[0]); + CLAMPED_FLOAT_TO_UBYTE(g, fc[1]); + CLAMPED_FLOAT_TO_UBYTE(b, fc[2]); + CLAMPED_FLOAT_TO_UBYTE(a, fc[3]); + + col = ((a << 24) | + (r << 16) | + (g << 8) | + (b << 0)); + + if (imesa->Setup[I810_CTXREG_CF1] != col) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_CF1] = col; + } + break; + } + case GL_TEXTURE_ENV_MODE: + imesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */ + break; + + case GL_TEXTURE_LOD_BIAS_EXT: + { + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; + i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData; + t->Setup[I810_TEXREG_MLC] &= ~(MLC_LOD_BIAS_MASK); + t->Setup[I810_TEXREG_MLC] |= i810ComputeLodBias(*param); + } + break; + + default: + break; + } +} + + + +#if 0 +static void i810TexImage1D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *pack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + i810TextureObjectPtr t = (i810TextureObjectPtr) texObj->DriverData; + if (t) { + i810SwapOutTexObj( imesa, t ); + } +} + +static void i810TexSubImage1D( GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *pack, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ +} +#endif + + +static void i810TexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject *t = (driTextureObject *) texObj->DriverData; + if (t) { + I810_FIREVERTICES( I810_CONTEXT(ctx) ); + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) i810AllocTexObj( ctx, texObj ); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + _mesa_store_teximage2d( ctx, target, level, internalFormat, + width, height, border, format, type, + pixels, packing, texObj, texImage ); + +} + +static void i810TexSubImage2D( GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject *t = (driTextureObject *)texObj->DriverData; + + if (t) { + I810_FIREVERTICES( I810_CONTEXT(ctx) ); + driSwapOutTextureObject( t ); + } + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, + height, format, type, pixels, packing, texObj, + texImage); + +} + + +static void i810BindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) +{ + if (!tObj->DriverData) { + i810AllocTexObj( ctx, tObj ); + } +} + + +static void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) +{ + driTextureObject * t = (driTextureObject *) tObj->DriverData; + if (t) { + i810ContextPtr imesa = I810_CONTEXT( ctx ); + if (imesa) + I810_FIREVERTICES( imesa ); + driDestroyTextureObject( t ); + } +} + +static const struct gl_texture_format * +i810ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) +{ + switch ( internalFormat ) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + if ( format == GL_BGRA ) { + if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { + return &_mesa_texformat_argb1555; + } + } + return &_mesa_texformat_argb4444; + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return &_mesa_texformat_rgb565; + + case GL_RGBA2: + case GL_RGBA4: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return &_mesa_texformat_argb4444; + + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + + 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_rgb565; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + return &_mesa_texformat_argb4444; + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_MESA || + type == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; + + default: + fprintf(stderr, "unexpected texture format in %s\n", __FUNCTION__); + return NULL; + } + + return NULL; /* never get here */ +} + +void i810InitTextureFuncs( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + + ctx->Driver.TexEnv = i810TexEnv; + ctx->Driver.ChooseTextureFormat = i810ChooseTextureFormat; + ctx->Driver.TexImage1D = _mesa_store_teximage1d; + ctx->Driver.TexImage2D = i810TexImage2D; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; + ctx->Driver.TexSubImage2D = i810TexSubImage2D; + ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; + ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; + ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; + ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; + ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; + ctx->Driver.BindTexture = i810BindTexture; + ctx->Driver.DeleteTexture = i810DeleteTexture; + ctx->Driver.TexParameter = i810TexParameter; + ctx->Driver.UpdateTexturePalette = 0; + ctx->Driver.IsTextureResident = driIsTextureResident; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + + driInitTextureObjects( ctx, &imesa->swapped, DRI_TEXMGR_DO_TEXTURE_2D); + +} diff --git a/src/mesa/drivers/dri/i810/i810tex.h b/src/mesa/drivers/dri/i810/i810tex.h new file mode 100644 index 00000000000..f0b4b88128f --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810tex.h @@ -0,0 +1,78 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + */ + +#ifndef I810TEX_INC +#define I810TEX_INC + +#include "mtypes.h" +#include "mm.h" + +#include "i810context.h" +#include "i810_3d_reg.h" +#include "texmem.h" + +#define I810_TEX_MAXLEVELS 11 + +/* For shared texture space managment, these texture objects may also + * be used as proxies for regions of texture memory containing other + * client's textures. Such proxy textures (not to be confused with GL + * proxy textures) are subject to the same LRU aging we use for our + * own private textures, and thus we have a mechanism where we can + * fairly decide between kicking out our own textures and those of + * other clients. + * + * Non-local texture objects have a valid MemBlock to describe the + * region managed by the other client, and can be identified by + * 't->globj == 0' + */ +struct i810_texture_object_t { + driTextureObject base; + + int Pitch; + int Height; + int texelBytes; + char *BufAddr; + + GLuint max_level; + + struct { + const struct gl_texture_image *image; + int offset; /* into BufAddr */ + int height; + int internalFormat; + } image[I810_TEX_MAXLEVELS]; + + GLuint Setup[I810_TEX_SETUP_SIZE]; + GLuint dirty; + +}; + +void i810UpdateTextureState( GLcontext *ctx ); +void i810InitTextureFuncs( GLcontext *ctx ); + +void i810DestroyTexObj( i810ContextPtr imesa, i810TextureObjectPtr t ); +int i810UploadTexImagesLocked( i810ContextPtr imesa, i810TextureObjectPtr t ); + +#endif diff --git a/src/mesa/drivers/dri/i810/i810texmem.c b/src/mesa/drivers/dri/i810/i810texmem.c new file mode 100644 index 00000000000..87f535dc23f --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810texmem.c @@ -0,0 +1,178 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * Texmem interface changes (C) 2003 Dave Airlie + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" +#include "colormac.h" +#include "mm.h" +#include "texformat.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810context.h" +#include "i810tex.h" +#include "i810state.h" +#include "i810ioctl.h" + + +void i810DestroyTexObj(i810ContextPtr imesa, i810TextureObjectPtr t) +{ + /* See if it was the driver's current object. + */ + if ( imesa != NULL ) { + if (imesa->CurrentTexObj[0] == t) { + imesa->CurrentTexObj[0] = 0; + imesa->dirty &= ~I810_UPLOAD_TEX0; + } + + if (imesa->CurrentTexObj[1] == t) { + imesa->CurrentTexObj[1] = 0; + imesa->dirty &= ~I810_UPLOAD_TEX1; + } + } +} + + + +/* From linux kernel i386 header files, copes with odd sizes better + * than COPY_DWORDS would: + */ +static __inline__ void * __memcpy(void * to, const void * from, size_t n) +{ +int d0, d1, d2; +__asm__ __volatile__( + "rep ; movsl\n\t" + "testb $2,%b4\n\t" + "je 1f\n\t" + "movsw\n" + "1:\ttestb $1,%b4\n\t" + "je 2f\n\t" + "movsb\n" + "2:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) + : "memory"); +return (to); +} + +/* Upload an image from mesa's internal copy. + */ +static void i810UploadTexLevel( i810ContextPtr imesa, + i810TextureObjectPtr t, int hwlevel ) +{ + const struct gl_texture_image *image = t->image[hwlevel].image; + int j; + + if (!image || !image->Data) + return; + + if (image->Width * image->TexFormat->TexelBytes == t->Pitch) { + GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[hwlevel].offset); + GLubyte *src = (GLubyte *)image->Data; + + memcpy( dst, src, t->Pitch * image->Height ); + } + else switch (image->TexFormat->TexelBytes) { + case 1: + { + GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[hwlevel].offset); + GLubyte *src = (GLubyte *)image->Data; + + for (j = 0 ; j < image->Height ; j++, dst += t->Pitch) { + __memcpy(dst, src, image->Width ); + src += image->Width; + } + } + break; + + case 2: + { + GLushort *dst = (GLushort *)(t->BufAddr + t->image[hwlevel].offset); + GLushort *src = (GLushort *)image->Data; + + for (j = 0 ; j < image->Height ; j++, dst += (t->Pitch/2)) { + __memcpy(dst, src, image->Width * 2 ); + src += image->Width; + } + } + break; + + default: + fprintf(stderr, "%s: Not supported texel size %d\n", + __FUNCTION__, image->TexFormat->TexelBytes); + } +} + +/* This is called with the lock held. May have to eject our own and/or + * other client's texture objects to make room for the upload. + */ +int i810UploadTexImagesLocked( i810ContextPtr imesa, i810TextureObjectPtr t ) +{ + int i; + int ofs; + int numLevels; + + /* Do we need to eject LRU texture objects? + */ + if (!t->base.memBlock) { + int heap; + + heap = driAllocateTexture( imesa->texture_heaps, imesa->nr_heaps, + (driTextureObject *) t); + + if ( heap == -1 ) { + return -1; + } + + ofs = t->base.memBlock->ofs; + t->BufAddr = imesa->i810Screen->tex.map + ofs; + t->Setup[I810_TEXREG_MI3] = imesa->i810Screen->textureOffset + ofs; + + if (t == imesa->CurrentTexObj[0]) + I810_STATECHANGE(imesa, I810_UPLOAD_TEX0); + + if (t == imesa->CurrentTexObj[1]) + I810_STATECHANGE(imesa, I810_UPLOAD_TEX1); + + /* i810UpdateTexLRU( imesa, t );*/ + } + driUpdateTextureLRU( (driTextureObject *) t ); + + if (imesa->texture_heaps[0]->timestamp >= GET_DISPATCH_AGE(imesa)) + i810WaitAgeLocked( imesa, imesa->texture_heaps[0]->timestamp ); + + numLevels = t->base.lastLevel - t->base.firstLevel + 1; + for (i = 0 ; i < numLevels ; i++) + if (t->base.dirty_images[0] & (1<base.dirty_images[0] = 0; + + return 0; +} diff --git a/src/mesa/drivers/dri/i810/i810texstate.c b/src/mesa/drivers/dri/i810/i810texstate.c new file mode 100644 index 00000000000..62193537163 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810texstate.c @@ -0,0 +1,766 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "simple_list.h" +#include "enums.h" + +#include "mm.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810context.h" +#include "i810tex.h" +#include "i810state.h" +#include "i810ioctl.h" + + + + +static void i810SetTexImages( i810ContextPtr imesa, + struct gl_texture_object *tObj ) +{ + GLuint height, width, pitch, i, textureFormat, log_pitch; + i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData; + const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel]; + GLint firstLevel, lastLevel, numLevels; + GLint log2Width, log2Height; + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + switch (baseImage->Format) { + case GL_RGB: + case GL_LUMINANCE: + t->texelBytes = 2; + textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_RGB565; + break; + case GL_ALPHA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + case GL_RGBA: + t->texelBytes = 2; + textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_ARGB4444; + break; + case GL_COLOR_INDEX: + textureFormat = MI1_FMT_8CI | MI1_PF_8CI_ARGB4444; + t->texelBytes = 1; + break; + case GL_YCBCR_MESA: + t->texelBytes = 2; + textureFormat = MI1_FMT_422 | MI1_PF_422_YCRCB_SWAP_Y + | MI1_COLOR_CONV_ENABLE; + break; + + default: + fprintf(stderr, "i810SetTexImages: bad image->Format\n" ); + return; + } + + /* Compute which mipmap levels we really want to send to the hardware. + * This depends on the base image size, GL_TEXTURE_MIN_LOD, + * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. + * Yes, this looks overly complicated, but it's all needed. + */ + if (tObj->MinFilter == GL_LINEAR || tObj->MinFilter == GL_NEAREST) { + firstLevel = lastLevel = tObj->BaseLevel; + } + else { + firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + } + + /* save these values */ + t->base.firstLevel = firstLevel; + t->base.lastLevel = lastLevel; + + numLevels = lastLevel - firstLevel + 1; + + log2Width = tObj->Image[firstLevel]->WidthLog2; + log2Height = tObj->Image[firstLevel]->HeightLog2; + + /* Figure out the amount of memory required to hold all the mipmap + * levels. Choose the smallest pitch to accomodate the largest + * mipmap: + */ + width = tObj->Image[firstLevel]->Width * t->texelBytes; + for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 ) + log_pitch++; + + /* All images must be loaded at this pitch. Count the number of + * lines required: + */ + for ( height = i = 0 ; i < numLevels ; i++ ) { + t->image[i].image = tObj->Image[firstLevel + i]; + t->image[i].offset = height * pitch; + t->image[i].internalFormat = baseImage->Format; + height += t->image[i].image->Height; + } + + t->Pitch = pitch; + t->base.totalSize = height*pitch; + t->max_level = i-1; + t->dirty = I810_UPLOAD_TEX0 | I810_UPLOAD_TEX1; + t->Setup[I810_TEXREG_MI1] = (MI1_MAP_0 | textureFormat | log_pitch); + t->Setup[I810_TEXREG_MI2] = (MI2_DIMENSIONS_ARE_LOG2 | + (log2Height << 16) | log2Width); + t->Setup[I810_TEXREG_MLL] = (GFX_OP_MAP_LOD_LIMITS | + MLL_MAP_0 | + MLL_UPDATE_MAX_MIP | + MLL_UPDATE_MIN_MIP | + ((numLevels - 1) << MLL_MIN_MIP_SHIFT)); + + LOCK_HARDWARE( imesa ); + i810UploadTexImagesLocked( imesa, t ); + UNLOCK_HARDWARE( imesa ); +} + +/* ================================================================ + * Texture combine functions + */ + +#define I810_DISABLE 0 +#define I810_PASSTHRU 1 +#define I810_REPLACE 2 +#define I810_MODULATE 3 +#define I810_DECAL 4 +#define I810_BLEND 5 +#define I810_ALPHA_BLEND 6 +#define I810_ADD 7 +#define I810_MAX_COMBFUNC 8 + + +static GLuint i810_color_combine[][I810_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ITERATED_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_UPDATE_OP | + MC_OP_ARG1 ), /* actually passthru */ + + /* Passthru + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ITERATED_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_UPDATE_OP | + MC_OP_ARG1 ), + + /* GL_REPLACE + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_UPDATE_OP | + MC_OP_ARG1 ), + + /* GL_MODULATE + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_MODULATE ), + + /* GL_DECAL + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_COLOR_FACTOR | + MC_UPDATE_ARG2 | + MC_ARG2_TEX0_COLOR | + MC_UPDATE_OP | + MC_OP_LIN_BLEND_TEX0_ALPHA ), + + /* GL_BLEND + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_COLOR_FACTOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_LIN_BLEND_TEX0_COLOR ), + + /* GL_BLEND according to alpha + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_LIN_BLEND_TEX0_ALPHA ), + + /* GL_ADD + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX0_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ITERATED_COLOR | + MC_UPDATE_OP | + MC_OP_ADD ), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage (Note: disables all subsequent stages) + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ONE | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_UPDATE_OP | + MC_OP_DISABLE ), + + + /* Passthru + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_CURRENT_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_UPDATE_OP | + MC_OP_ARG1 ), + + /* GL_REPLACE + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX1_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_UPDATE_OP | + MC_OP_ARG1 ), + + /* GL_MODULATE + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX1_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_CURRENT_COLOR | + MC_UPDATE_OP | + MC_OP_MODULATE ), + + /* GL_DECAL + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_COLOR_FACTOR | + MC_UPDATE_ARG2 | + MC_ARG2_TEX1_COLOR | + MC_UPDATE_OP | + MC_OP_LIN_BLEND_TEX1_ALPHA ), + + /* GL_BLEND + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_COLOR_FACTOR | + MC_UPDATE_ARG2 | + MC_ARG2_CURRENT_COLOR | + MC_UPDATE_OP | + MC_OP_LIN_BLEND_TEX1_COLOR ), + + /* GL_BLEND according to alpha + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX1_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_CURRENT_COLOR | + MC_UPDATE_OP | + MC_OP_LIN_BLEND_TEX1_ALPHA ), + + /* GL_ADD + */ + ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_TEX1_COLOR | + MC_UPDATE_ARG2 | + MC_ARG2_CURRENT_COLOR | + MC_UPDATE_OP | + MC_OP_ADD ), + } +}; + +static GLuint i810_alpha_combine[][I810_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ), + + /* Passthru + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ), + + /* GL_REPLACE + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG2 ), + + /* GL_MODULATE + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_MODULATE ), + + /* GL_DECAL + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ALPHA_FACTOR | + MA_UPDATE_ARG2 | + MA_ARG2_ALPHA_FACTOR | + MA_UPDATE_OP | + MA_OP_ARG1 ), + + /* GL_BLEND + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ALPHA_FACTOR | + MA_UPDATE_ARG2 | + MA_ARG2_ITERATED_ALPHA | + MA_UPDATE_OP | + MA_OP_LIN_BLEND_TEX0_ALPHA ), + + /* GL_BLEND according to alpha (same as above) + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ALPHA_FACTOR | + MA_UPDATE_ARG2 | + MA_ARG2_ITERATED_ALPHA | + MA_UPDATE_OP | + MA_OP_LIN_BLEND_TEX0_ALPHA ), + + /* GL_ADD + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX0_ALPHA | + MA_UPDATE_OP | + MA_OP_ADD ), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ), + + /* Passthru + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG1 ), + + /* GL_REPLACE + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX1_ALPHA | + MA_UPDATE_OP | + MA_OP_ARG2 ), + + /* GL_MODULATE + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX1_ALPHA | + MA_UPDATE_OP | + MA_OP_MODULATE ), + + /* GL_DECAL + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_ALPHA_FACTOR | + MA_UPDATE_ARG2 | + MA_ARG2_ALPHA_FACTOR | + MA_UPDATE_OP | + MA_OP_ARG1 ), + + /* GL_BLEND + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_ALPHA_FACTOR | + MA_UPDATE_ARG2 | + MA_ARG2_ITERATED_ALPHA | + MA_UPDATE_OP | + MA_OP_LIN_BLEND_TEX1_ALPHA ), + + /* GL_BLEND according to alpha (same as above) + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_ALPHA_FACTOR | + MA_UPDATE_ARG2 | + MA_ARG2_ITERATED_ALPHA | + MA_UPDATE_OP | + MA_OP_LIN_BLEND_TEX1_ALPHA ), + + /* GL_ADD + */ + ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_UPDATE_ARG2 | + MA_ARG2_TEX1_ALPHA | + MA_UPDATE_OP | + MA_OP_ADD ), + } + +}; + + + +static void i810UpdateTexEnv( GLcontext *ctx, GLuint unit ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + const struct gl_texture_object *tObj = texUnit->_Current; + const GLuint format = tObj->Image[tObj->BaseLevel]->Format; + GLuint color_combine, alpha_combine; + + switch (texUnit->EnvMode) { + case GL_REPLACE: + if (format == GL_ALPHA) { + color_combine = i810_color_combine[unit][I810_PASSTHRU]; + alpha_combine = i810_alpha_combine[unit][I810_REPLACE]; + } else if (format == GL_LUMINANCE || format == GL_RGB) { + color_combine = i810_color_combine[unit][I810_REPLACE]; + alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + } else { + color_combine = i810_color_combine[unit][I810_REPLACE]; + alpha_combine = i810_alpha_combine[unit][I810_REPLACE]; + } + break; + + case GL_MODULATE: + if (format == GL_ALPHA) { + color_combine = i810_color_combine[unit][I810_PASSTHRU]; + alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + } else { + color_combine = i810_color_combine[unit][I810_MODULATE]; + alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + } + break; + + case GL_DECAL: + switch (format) { + case GL_RGBA: + color_combine = i810_color_combine[unit][I810_ALPHA_BLEND]; + alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + break; + case GL_RGB: + color_combine = i810_color_combine[unit][I810_REPLACE]; + alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = i810_color_combine[unit][I810_PASSTHRU]; + alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_BLEND: + switch (format) { + case GL_RGB: + case GL_LUMINANCE: + color_combine = i810_color_combine[unit][I810_BLEND]; + alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + break; + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + color_combine = i810_color_combine[unit][I810_BLEND]; + alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + break; + case GL_ALPHA: + color_combine = i810_color_combine[unit][I810_PASSTHRU]; + alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + break; + case GL_INTENSITY: + color_combine = i810_color_combine[unit][I810_BLEND]; + alpha_combine = i810_alpha_combine[unit][I810_BLEND]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_ADD: + switch (format) { + case GL_RGB: + case GL_LUMINANCE: + color_combine = i810_color_combine[unit][I810_ADD]; + alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + break; + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + color_combine = i810_color_combine[unit][I810_ADD]; + alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + break; + case GL_ALPHA: + color_combine = i810_color_combine[unit][I810_PASSTHRU]; + alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + break; + case GL_INTENSITY: + color_combine = i810_color_combine[unit][I810_ADD]; + alpha_combine = i810_alpha_combine[unit][I810_ADD]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + default: + return; + } + + if (alpha_combine != imesa->Setup[I810_CTXREG_MA0 + unit] || + color_combine != imesa->Setup[I810_CTXREG_MC0 + unit]) + { + I810_STATECHANGE( imesa, I810_UPLOAD_CTX ); + imesa->Setup[I810_CTXREG_MA0 + unit] = alpha_combine; + imesa->Setup[I810_CTXREG_MC0 + unit] = color_combine; + } +} + + + + +static void i810UpdateTexUnit( GLcontext *ctx, GLuint unit ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + + if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT) + { + struct gl_texture_object *tObj = texUnit->_Current; + i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData; + + /* Upload teximages (not pipelined) + */ + if (t->base.dirty_images[0]) { + I810_FIREVERTICES(imesa); + i810SetTexImages( imesa, tObj ); + if (!t->base.memBlock) { + FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); + return; + } + } + + if (tObj->Image[tObj->BaseLevel]->Border > 0) { + FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); + return; + } + + /* Update state if this is a different texture object to last + * time. + */ + if (imesa->CurrentTexObj[unit] != t) { + I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<CurrentTexObj[unit] = t; + t->base.bound |= (1U << unit); + + driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked */ + + } + + /* Update texture environment if texture object image format or + * texture environment state has changed. + */ + if (tObj->Image[tObj->BaseLevel]->Format != imesa->TexEnvImageFmt[unit]) { + imesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format; + i810UpdateTexEnv( ctx, unit ); + } + } + else if (texUnit->_ReallyEnabled) { + FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); + } + else /*if (imesa->CurrentTexObj[unit])*/ { + imesa->CurrentTexObj[unit] = 0; + imesa->TexEnvImageFmt[unit] = 0; + imesa->dirty &= ~(I810_UPLOAD_TEX0<Setup[I810_CTXREG_MA0 + unit] = + i810_alpha_combine[unit][I810_DISABLE]; + imesa->Setup[I810_CTXREG_MC0 + unit] = + i810_color_combine[unit][I810_DISABLE]; + I810_STATECHANGE( imesa, I810_UPLOAD_CTX ); + } +} + + +void i810UpdateTextureState( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + /* fprintf(stderr, "%s\n", __FUNCTION__); */ + FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_FALSE ); + i810UpdateTexUnit( ctx, 0 ); + i810UpdateTexUnit( ctx, 1 ); +} + + + diff --git a/src/mesa/drivers/dri/i810/i810tris.c b/src/mesa/drivers/dri/i810/i810tris.c new file mode 100644 index 00000000000..364b571152b --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810tris.c @@ -0,0 +1,867 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.c,v 1.7 2002/10/30 12:51:33 alanh Exp $ */ +/************************************************************************** + +Copyright 2001 VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "mtypes.h" +#include "macros.h" +#include "enums.h" +#include "colormac.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810tris.h" +#include "i810state.h" +#include "i810vb.h" +#include "i810ioctl.h" + +static void i810RenderPrimitive( GLcontext *ctx, GLenum prim ); + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#if defined(USE_X86_ASM) +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (j), "=D" (vb), "=S" (__tmp) \ + : "0" (vertsize), \ + "D" ((long)vb), \ + "S" ((long)v) ); \ +} while (0) +#else +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + for ( j = 0 ; j < vertsize ; j++ ) \ + vb[j] = ((GLuint *)v)[j]; \ + vb += vertsize; \ +} while (0) +#endif + +static void __inline__ i810_draw_triangle( i810ContextPtr imesa, + i810VertexPtr v0, + i810VertexPtr v1, + i810VertexPtr v2 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i810AllocDmaLow( imesa, 3 * 4 * vertsize ); + int j; + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v2 ); +} + + +static void __inline__ i810_draw_quad( i810ContextPtr imesa, + i810VertexPtr v0, + i810VertexPtr v1, + i810VertexPtr v2, + i810VertexPtr v3 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i810AllocDmaLow( imesa, 6 * 4 * vertsize ); + int j; + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v3 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v2 ); + COPY_DWORDS( j, vb, vertsize, v3 ); +} + + +static __inline__ void i810_draw_point( i810ContextPtr imesa, + i810VertexPtr tmp ) +{ + GLfloat sz = imesa->glCtx->Point._Size * .5; + int vertsize = imesa->vertex_size; + GLuint *vb = i810AllocDmaLow( imesa, 2 * 4 * vertsize ); + int j; + + /* Draw a point as a horizontal line. + */ + *(float *)&vb[0] = tmp->v.x - sz + 0.125; + for (j = 1 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x + sz + 0.125; + for (j = 1 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; +} + + +static __inline__ void i810_draw_line( i810ContextPtr imesa, + i810VertexPtr v0, + i810VertexPtr v1 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i810AllocDmaLow( imesa, 2 * 4 * vertsize ); + int j; + + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); +} + + + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (0) fprintf(stderr, "hw TRI\n"); \ + if (DO_FALLBACK) \ + imesa->draw_tri( imesa, a, b, c ); \ + else \ + i810_draw_triangle( imesa, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (0) fprintf(stderr, "hw QUAD\n"); \ + if (DO_FALLBACK) { \ + imesa->draw_tri( imesa, a, b, d ); \ + imesa->draw_tri( imesa, b, c, d ); \ + } else \ + i810_draw_quad( imesa, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (0) fprintf(stderr, "hw LINE\n"); \ + if (DO_FALLBACK) \ + imesa->draw_line( imesa, v0, v1 ); \ + else \ + i810_draw_line( imesa, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (0) fprintf(stderr, "hw POINT\n"); \ + if (DO_FALLBACK) \ + imesa->draw_point( imesa, v0 ); \ + else \ + i810_draw_point( imesa, v0 ); \ +} while (0) + + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define I810_OFFSET_BIT 0x01 +#define I810_TWOSIDE_BIT 0x02 +#define I810_UNFILLED_BIT 0x04 +#define I810_FALLBACK_BIT 0x08 +#define I810_MAX_TRIFUNC 0x10 + + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[I810_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & I810_FALLBACK_BIT) +#define DO_OFFSET (IND & I810_OFFSET_BIT) +#define DO_UNFILLED (IND & I810_UNFILLED_BIT) +#define DO_TWOSIDE (IND & I810_TWOSIDE_BIT) +#define DO_FLAT 0 +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 1 +#define HAVE_BACK_COLORS 0 +#define HAVE_HW_FLATSHADE 1 +#define VERTEX i810Vertex +#define TAB rast_tab + +/* Only used to pull back colors into vertices (ie, we know color is + * floating point). + */ +#define I810_COLOR( dst, src ) \ +do { \ + dst[0] = src[2]; \ + dst[1] = src[1]; \ + dst[2] = src[0]; \ + dst[3] = src[3]; \ +} while (0) + +#define I810_SPEC( dst, src ) \ +do { \ + dst[0] = src[2]; \ + dst[1] = src[1]; \ + dst[2] = src[0]; \ +} while (0) + + +#define DEPTH_SCALE (1.0/0xffff) +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW( a ) (a > 0) +#define GET_VERTEX(e) (imesa->verts + (e<vertex_stride_shift)) + +#define VERT_SET_RGBA( v, c ) I810_COLOR( v->ub4[coloroffset], c ) +#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] +#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx] + +#define VERT_SET_SPEC( v, c ) if (havespec) I810_SPEC( v->ub4[5], c ) +#define VERT_COPY_SPEC( v0, v1 ) if (havespec) COPY_3V(v0->ub4[5], v1->ub4[5]) +#define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5] +#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx] + +#define LOCAL_VARS(n) \ + i810ContextPtr imesa = I810_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = (imesa->vertex_size == 4 ? 3 : 4); \ + GLboolean havespec = (imesa->vertex_size > 4); \ + (void) color; (void) spec; (void) coloroffset; (void) havespec; + + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +static const GLuint hw_prim[GL_POLYGON+1] = { + PR_LINES, + PR_LINES, + PR_LINES, + PR_LINES, + PR_TRIANGLES, + PR_TRIANGLES, + PR_TRIANGLES, + PR_TRIANGLES, + PR_TRIANGLES, + PR_TRIANGLES +}; + +#define RASTERIZE(x) if (imesa->hw_primitive != hw_prim[x]) \ + i810RasterPrimitive( ctx, x, hw_prim[x] ) +#define RENDER_PRIMITIVE imesa->render_primitive +#define TAG(x) x +#define IND I810_FALLBACK_BIT +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_OFFSET_BIT|I810_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_TWOSIDE_BIT|I810_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_OFFSET_BIT|I810_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_TWOSIDE_BIT|I810_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_UNFILLED_BIT|I810_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_OFFSET_BIT|I810_UNFILLED_BIT|I810_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_TWOSIDE_BIT|I810_UNFILLED_BIT|I810_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_UNFILLED_BIT| \ + I810_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + + +static void init_rast_tab( void ) +{ + init(); + init_offset(); + init_twoside(); + init_twoside_offset(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_twoside_offset_unfilled(); + init_fallback(); + init_offset_fallback(); + init_twoside_fallback(); + init_twoside_offset_fallback(); + init_unfilled_fallback(); + init_offset_unfilled_fallback(); + init_twoside_unfilled_fallback(); + init_twoside_offset_unfilled_fallback(); +} + + +/*********************************************************************** + * Rasterization fallback helpers * + ***********************************************************************/ + + +/* This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +i810_fallback_tri( i810ContextPtr imesa, + i810Vertex *v0, + i810Vertex *v1, + i810Vertex *v2 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[3]; + i810_translate_vertex( ctx, v0, &v[0] ); + i810_translate_vertex( ctx, v1, &v[1] ); + i810_translate_vertex( ctx, v2, &v[2] ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); +} + + +static void +i810_fallback_line( i810ContextPtr imesa, + i810Vertex *v0, + i810Vertex *v1 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[2]; + i810_translate_vertex( ctx, v0, &v[0] ); + i810_translate_vertex( ctx, v1, &v[1] ); + _swrast_Line( ctx, &v[0], &v[1] ); +} + + +static void +i810_fallback_point( i810ContextPtr imesa, + i810Vertex *v0 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[1]; + i810_translate_vertex( ctx, v0, &v[0] ); + _swrast_Point( ctx, &v[0] ); +} + + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define IND 0 +#define V(x) (i810Vertex *)(vertptr + ((x)<verts; \ + const GLuint vertshift = imesa->vertex_stride_shift; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) x +#define TAG(x) i810_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) i810_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + + + +static void i810RenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint prim = imesa->render_primitive; + + /* Render the new vertices as an unclipped polygon. + */ + { + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, + PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; + } + + /* Restore the render primitive + */ + if (prim != GL_POLYGON) + tnl->Driver.Render.PrimitiveNotify( ctx, prim ); +} + +static void i810RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Line( ctx, ii, jj ); +} + +static void i810FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLuint vertsize = imesa->vertex_size; + GLuint *vb = i810AllocDmaLow( imesa, (n-2) * 3 * 4 * vertsize ); + GLubyte *vertptr = (GLubyte *)imesa->verts; + const GLuint vertshift = imesa->vertex_stride_shift; + const GLuint *start = (const GLuint *)V(elts[0]); + int i,j; + + for (i = 2 ; i < n ; i++) { + COPY_DWORDS( j, vb, vertsize, V(elts[i-1]) ); + COPY_DWORDS( j, vb, vertsize, V(elts[i]) ); + COPY_DWORDS( j, vb, vertsize, start ); + } +} + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + +/*********************************************************************** + * Rasterization fallback helpers * + ***********************************************************************/ + + + +#define _I810_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET | \ + _DD_NEW_TRI_STIPPLE | \ + _NEW_POLYGONSTIPPLE) + +#define POINT_FALLBACK (0) +#define LINE_FALLBACK (DD_LINE_STIPPLE) +#define TRI_FALLBACK (0) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\ + DD_TRI_STIPPLE) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) + +static void i810ChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + if (I810_DEBUG & DEBUG_STATE) + fprintf(stderr,"\n%s\n",__FUNCTION__); + + if (flags & (ANY_FALLBACK_FLAGS|ANY_RASTER_FLAGS)) { + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= I810_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= I810_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= I810_UNFILLED_BIT; + } + + imesa->draw_point = i810_draw_point; + imesa->draw_line = i810_draw_line; + imesa->draw_tri = i810_draw_triangle; + + /* Hook in fallbacks for specific primitives. + */ + if (flags & ANY_FALLBACK_FLAGS) + { + if (flags & POINT_FALLBACK) + imesa->draw_point = i810_fallback_point; + + if (flags & LINE_FALLBACK) + imesa->draw_line = i810_fallback_line; + + if (flags & TRI_FALLBACK) + imesa->draw_tri = i810_fallback_tri; + + if ((flags & DD_TRI_STIPPLE) && !imesa->stipple_in_hw) + imesa->draw_tri = i810_fallback_tri; + + index |= I810_FALLBACK_BIT; + } + } + + if (imesa->RenderIndex != index) { + imesa->RenderIndex = index; + + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = i810_render_tab_verts; + tnl->Driver.Render.PrimTabElts = i810_render_tab_elts; + tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ + tnl->Driver.Render.ClippedPolygon = i810FastRenderClippedPoly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = i810RenderClippedLine; + tnl->Driver.Render.ClippedPolygon = i810RenderClippedPoly; + } + } +} + +static const GLenum reduced_prim[GL_POLYGON+1] = { + GL_POINTS, + GL_LINES, + GL_LINES, + GL_LINES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES, + GL_TRIANGLES +}; + + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + + + +/* Determine the rasterized primitive when not drawing unfilled + * polygons. + * + * Used only for the default render stage which always decomposes + * primitives to trianges/lines/points. For the accelerated stage, + * which renders strips as strips, the equivalent calculations are + * performed in i810render.c. + */ +static void i810RenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLuint rprim = reduced_prim[prim]; + + imesa->render_primitive = prim; + + if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + if (imesa->reduced_primitive != rprim || + hw_prim[prim] != imesa->hw_primitive) { + i810RasterPrimitive( ctx, rprim, hw_prim[prim] ); + } +} + +static void i810RunPipeline( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + + if (imesa->new_state) { + if (imesa->new_state & _NEW_TEXTURE) + i810UpdateTextureState( ctx ); /* may modify imesa->new_state */ + + if (!imesa->Fallback) { + if (imesa->new_state & _I810_NEW_VERTEX) + i810ChooseVertexState( ctx ); + + if (imesa->new_state & _I810_NEW_RENDERSTATE) + i810ChooseRenderState( ctx ); + } + + imesa->new_state = 0; + } + + _tnl_run_pipeline( ctx ); +} + +static void i810RenderStart( GLcontext *ctx ) +{ + /* Check for projective textureing. Make sure all texcoord + * pointers point to something. (fix in mesa?) + */ + i810CheckTexSizes( ctx ); +} + +static void i810RenderFinish( GLcontext *ctx ) +{ + if (I810_CONTEXT(ctx)->RenderIndex & I810_FALLBACK_BIT) + _swrast_flush( ctx ); +} + + + + +/* System to flush dma and emit state changes based on the rasterized + * primitive. + */ +void i810RasterPrimitive( GLcontext *ctx, + GLenum rprim, + GLuint hwprim ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLuint st1 = imesa->Setup[I810_CTXREG_ST1]; + GLuint aa = imesa->Setup[I810_CTXREG_AA]; + GLuint lcs = imesa->Setup[I810_CTXREG_LCS]; + + st1 &= ~ST1_ENABLE; + aa &= ~AA_ENABLE; + + if (I810_DEBUG & DEBUG_PRIMS) { + /* Prints reduced prim, and hw prim */ + char *prim_name = "Unknown"; + + switch(hwprim) { + case PR_LINES: + prim_name = "Lines"; + break; + case PR_LINESTRIP: + prim_name = "LineStrip"; + break; + case PR_TRIANGLES: + prim_name = "Triangles"; + break; + case PR_TRISTRIP_0: + prim_name = "TriStrip_0"; + break; + case PR_TRIFAN: + prim_name = "TriFan"; + break; + case PR_POLYGON: + prim_name = "Polygons"; + break; + default: + break; + } + + fprintf(stderr, "%s : rprim(%s), hwprim(%s)\n", + __FUNCTION__, + _mesa_lookup_enum_by_nr(rprim), + prim_name); + } + + switch (rprim) { + case GL_TRIANGLES: + if (ctx->Polygon.StippleFlag) + st1 |= ST1_ENABLE; + if (ctx->Polygon.SmoothFlag) + aa |= AA_ENABLE; + break; + case GL_LINES: + lcs &= ~(LCS_LINEWIDTH_3_0|LCS_LINEWIDTH_0_5); + lcs |= imesa->LcsLineWidth; + if (ctx->Line.SmoothFlag) { + aa |= AA_ENABLE; + lcs |= LCS_LINEWIDTH_0_5; + } + break; + case GL_POINTS: + lcs &= ~(LCS_LINEWIDTH_3_0|LCS_LINEWIDTH_0_5); + lcs |= imesa->LcsPointSize; + if (ctx->Point.SmoothFlag) { + aa |= AA_ENABLE; + lcs |= LCS_LINEWIDTH_0_5; + } + break; + default: + return; + } + + imesa->reduced_primitive = rprim; + + if (st1 != imesa->Setup[I810_CTXREG_ST1] || + aa != imesa->Setup[I810_CTXREG_AA] || + lcs != imesa->Setup[I810_CTXREG_LCS]) + { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->hw_primitive = hwprim; + imesa->Setup[I810_CTXREG_LCS] = lcs; + imesa->Setup[I810_CTXREG_ST1] = st1; + imesa->Setup[I810_CTXREG_AA] = aa; + } + else if (hwprim != imesa->hw_primitive) { + I810_STATECHANGE(imesa, 0); + imesa->hw_primitive = hwprim; + } +} + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ +static char *fallbackStrings[] = { + "Texture", + "Draw buffer", + "Read buffer", + "Color mask", + "Render mode", + "Stencil", + "Stipple", + "User disable" +}; + + +static char *getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + +void i810Fallback( i810ContextPtr imesa, GLuint bit, GLboolean mode ) +{ + GLcontext *ctx = imesa->glCtx; + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldfallback = imesa->Fallback; + + if (0) fprintf(stderr, "%s old %x bit %x mode %d\n", __FUNCTION__, + imesa->Fallback, bit, mode ); + + if (mode) { + imesa->Fallback |= bit; + if (oldfallback == 0) { + I810_FIREVERTICES(imesa); + if (I810_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "ENTER FALLBACK %s\n", getFallbackString( bit )); + _swsetup_Wakeup( ctx ); + imesa->RenderIndex = ~0; + } + } + else { + imesa->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + if (I810_DEBUG & DEBUG_FALLBACKS) + fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString( bit )); + tnl->Driver.Render.Start = i810RenderStart; + tnl->Driver.Render.PrimitiveNotify = i810RenderPrimitive; + tnl->Driver.Render.Finish = i810RenderFinish; + tnl->Driver.Render.BuildVertices = i810BuildVertices; + imesa->new_state |= (_I810_NEW_RENDERSTATE|_I810_NEW_VERTEX); + } + } +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + + +void i810InitTriFuncs( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.RunPipeline = i810RunPipeline; + tnl->Driver.Render.Start = i810RenderStart; + tnl->Driver.Render.Finish = i810RenderFinish; + tnl->Driver.Render.PrimitiveNotify = i810RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = i810BuildVertices; +} diff --git a/src/mesa/drivers/dri/i810/i810tris.h b/src/mesa/drivers/dri/i810/i810tris.h new file mode 100644 index 00000000000..06c8b3fcd53 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810tris.h @@ -0,0 +1,36 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.h,v 1.10 2002/02/22 21:33:04 dawes Exp $ */ + +#ifndef I810TRIS_INC +#define I810TRIS_INC + +#include "mtypes.h" + +extern void i810PrintRenderState( const char *msg, GLuint state ); +extern void i810InitTriFuncs( GLcontext *ctx ); +extern void i810RasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ); + +#endif diff --git a/src/mesa/drivers/dri/i810/i810vb.c b/src/mesa/drivers/dri/i810/i810vb.c new file mode 100644 index 00000000000..ada7f6db853 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810vb.c @@ -0,0 +1,505 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.c,v 1.13 2003/03/26 20:43:48 tsi Exp $ */ + + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "macros.h" +#include "colormac.h" + +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810context.h" +#include "i810vb.h" +#include "i810ioctl.h" +#include "i810tris.h" +#include "i810state.h" + + +#define I810_TEX1_BIT 0x1 +#define I810_TEX0_BIT 0x2 +#define I810_RGBA_BIT 0x4 +#define I810_SPEC_BIT 0x8 +#define I810_FOG_BIT 0x10 +#define I810_XYZW_BIT 0x20 +#define I810_PTEX_BIT 0x40 +#define I810_MAX_SETUP 0x80 + +static struct { + void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint ); + interp_func interp; + copy_pv_func copy_pv; + GLboolean (*check_tex_sizes)( GLcontext *ctx ); + GLuint vertex_size; + GLuint vertex_stride_shift; + GLuint vertex_format; +} setup_tab[I810_MAX_SETUP]; + +#define TINY_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \ + VF_TEXCOORD_COUNT_0 | \ + VF_RGBA_ENABLE | \ + VF_XYZ) + +#define NOTEX_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \ + VF_TEXCOORD_COUNT_0 | \ + VF_SPEC_FOG_ENABLE | \ + VF_RGBA_ENABLE | \ + VF_XYZW) + +#define TEX0_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \ + VF_TEXCOORD_COUNT_1 | \ + VF_SPEC_FOG_ENABLE | \ + VF_RGBA_ENABLE | \ + VF_XYZW) + +#define TEX1_VERTEX_FORMAT (GFX_OP_VERTEX_FMT | \ + VF_TEXCOORD_COUNT_2 | \ + VF_SPEC_FOG_ENABLE | \ + VF_RGBA_ENABLE | \ + VF_XYZW) + +#define PROJ_TEX1_VERTEX_FORMAT 0 +#define TEX2_VERTEX_FORMAT 0 +#define TEX3_VERTEX_FORMAT 0 +#define PROJ_TEX3_VERTEX_FORMAT 0 + +#define DO_XYZW (IND & I810_XYZW_BIT) +#define DO_RGBA (IND & I810_RGBA_BIT) +#define DO_SPEC (IND & I810_SPEC_BIT) +#define DO_FOG (IND & I810_FOG_BIT) +#define DO_TEX0 (IND & I810_TEX0_BIT) +#define DO_TEX1 (IND & I810_TEX1_BIT) +#define DO_TEX2 0 +#define DO_TEX3 0 +#define DO_PTEX (IND & I810_PTEX_BIT) + +#define VERTEX i810Vertex +#define VERTEX_COLOR i810_color_t +#define GET_VIEWPORT_MAT() I810_CONTEXT(ctx)->ViewportMatrix.m +#define GET_TEXSOURCE(n) n +#define GET_VERTEX_FORMAT() I810_CONTEXT(ctx)->Setup[I810_CTXREG_VF] +#define GET_VERTEX_STORE() I810_CONTEXT(ctx)->verts +#define GET_VERTEX_STRIDE_SHIFT() I810_CONTEXT(ctx)->vertex_stride_shift +#define GET_UBYTE_COLOR_STORE() &I810_CONTEXT(ctx)->UbyteColor +#define GET_UBYTE_SPEC_COLOR_STORE() &I810_CONTEXT(ctx)->UbyteSecondaryColor +#define INVALIDATE_STORED_VERTICES() + +#define HAVE_HW_VIEWPORT 0 +#define HAVE_HW_DIVIDE 0 +#define HAVE_RGBA_COLOR 0 +#define HAVE_TINY_VERTICES 1 +#define HAVE_NOTEX_VERTICES 1 +#define HAVE_TEX0_VERTICES 1 +#define HAVE_TEX1_VERTICES 1 +#define HAVE_TEX2_VERTICES 0 +#define HAVE_TEX3_VERTICES 0 +#define HAVE_PTEX_VERTICES 0 + +#define UNVIEWPORT_VARS GLfloat h = I810_CONTEXT(ctx)->driDrawable->h +#define UNVIEWPORT_X(x) x - SUBPIXEL_X +#define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y +#define UNVIEWPORT_Z(z) z * (float)0xffff + +#define PTEX_FALLBACK() FALLBACK(I810_CONTEXT(ctx), I810_FALLBACK_TEXTURE, 1) + +#define IMPORT_FLOAT_COLORS i810_import_float_colors +#define IMPORT_FLOAT_SPEC_COLORS i810_import_float_spec_colors + +#define INTERP_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].interp +#define COPY_PV_VERTEX setup_tab[I810_CONTEXT(ctx)->SetupIndex].copy_pv + + +/*********************************************************************** + * Generate pv-copying and translation functions * + ***********************************************************************/ + +#define TAG(x) i810_##x +#include "tnl_dd/t_dd_vb.c" + +/*********************************************************************** + * Generate vertex emit and interp functions * + ***********************************************************************/ + + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT) +#define TAG(x) x##_wg +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT) +#define TAG(x) x##_wgs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT) +#define TAG(x) x##_wgt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT) +#define TAG(x) x##_wgt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_TEX0_BIT|I810_PTEX_BIT) +#define TAG(x) x##_wgpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT) +#define TAG(x) x##_wgst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\ + I810_TEX1_BIT) +#define TAG(x) x##_wgst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\ + I810_PTEX_BIT) +#define TAG(x) x##_wgspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT) +#define TAG(x) x##_wgf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT) +#define TAG(x) x##_wgfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT) +#define TAG(x) x##_wgft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\ + I810_TEX1_BIT) +#define TAG(x) x##_wgft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|\ + I810_PTEX_BIT) +#define TAG(x) x##_wgfpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\ + I810_TEX0_BIT) +#define TAG(x) x##_wgfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\ + I810_TEX0_BIT|I810_TEX1_BIT) +#define TAG(x) x##_wgfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_XYZW_BIT|I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|\ + I810_TEX0_BIT|I810_PTEX_BIT) +#define TAG(x) x##_wgfspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_TEX0_BIT) +#define TAG(x) x##_t0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_TEX0_BIT|I810_TEX1_BIT) +#define TAG(x) x##_t0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_FOG_BIT) +#define TAG(x) x##_f +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_FOG_BIT|I810_TEX0_BIT) +#define TAG(x) x##_ft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT) +#define TAG(x) x##_ft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT) +#define TAG(x) x##_g +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_SPEC_BIT) +#define TAG(x) x##_gs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_TEX0_BIT) +#define TAG(x) x##_gt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_TEX0_BIT|I810_TEX1_BIT) +#define TAG(x) x##_gt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT) +#define TAG(x) x##_gst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_SPEC_BIT|I810_TEX0_BIT|I810_TEX1_BIT) +#define TAG(x) x##_gst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_FOG_BIT) +#define TAG(x) x##_gf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT) +#define TAG(x) x##_gfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT) +#define TAG(x) x##_gft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_TEX0_BIT|I810_TEX1_BIT) +#define TAG(x) x##_gft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT) +#define TAG(x) x##_gfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (I810_RGBA_BIT|I810_FOG_BIT|I810_SPEC_BIT|I810_TEX0_BIT|\ + I810_TEX1_BIT) +#define TAG(x) x##_gfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + + +static void init_setup_tab( void ) +{ + init_wg(); + init_wgs(); + init_wgt0(); + init_wgt0t1(); + init_wgpt0(); + init_wgst0(); + init_wgst0t1(); + init_wgspt0(); + init_wgf(); + init_wgfs(); + init_wgft0(); + init_wgft0t1(); + init_wgfpt0(); + init_wgfst0(); + init_wgfst0t1(); + init_wgfspt0(); + init_t0(); + init_t0t1(); + init_f(); + init_ft0(); + init_ft0t1(); + init_g(); + init_gs(); + init_gt0(); + init_gt0t1(); + init_gst0(); + init_gst0t1(); + init_gf(); + init_gfs(); + init_gft0(); + init_gft0t1(); + init_gfst0(); + init_gfst0t1(); +} + + + +void i810PrintSetupFlags(char *msg, GLuint flags ) +{ + fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & I810_XYZW_BIT) ? " xyzw," : "", + (flags & I810_RGBA_BIT) ? " rgba," : "", + (flags & I810_SPEC_BIT) ? " spec," : "", + (flags & I810_FOG_BIT) ? " fog," : "", + (flags & I810_TEX0_BIT) ? " tex-0," : "", + (flags & I810_TEX1_BIT) ? " tex-1," : ""); +} + + + +void i810CheckTexSizes( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + i810ContextPtr imesa = I810_CONTEXT( ctx ); + + if (!setup_tab[imesa->SetupIndex].check_tex_sizes(ctx)) { + /* Invalidate stored verts + */ + imesa->SetupNewInputs = ~0; + imesa->SetupIndex |= I810_PTEX_BIT; + + if (!imesa->Fallback && + !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + tnl->Driver.Render.Interp = setup_tab[imesa->SetupIndex].interp; + tnl->Driver.Render.CopyPV = setup_tab[imesa->SetupIndex].copy_pv; + } + if (imesa->Fallback) { + tnl->Driver.Render.Start(ctx); + } + } +} + +void i810BuildVertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLubyte *v = ((GLubyte *)imesa->verts + (start<vertex_stride_shift)); + GLuint stride = 1<vertex_stride_shift; + + if (0) fprintf(stderr, "%s\n", __FUNCTION__); + + newinputs |= imesa->SetupNewInputs; + imesa->SetupNewInputs = 0; + + if (!newinputs) + return; + + if (newinputs & VERT_BIT_CLIP) { + setup_tab[imesa->SetupIndex].emit( ctx, start, count, v, stride ); + } else { + GLuint ind = 0; + + if (newinputs & VERT_BIT_COLOR0) + ind |= I810_RGBA_BIT; + + if (newinputs & VERT_BIT_COLOR1) + ind |= I810_SPEC_BIT; + + if (newinputs & VERT_BIT_TEX0) + ind |= I810_TEX0_BIT; + + if (newinputs & VERT_BIT_TEX1) + ind |= I810_TEX1_BIT; + + if (newinputs & VERT_BIT_FOG) + ind |= I810_FOG_BIT; + + if (imesa->SetupIndex & I810_PTEX_BIT) + ind = ~0; + + ind &= imesa->SetupIndex; + + if (ind) { + setup_tab[ind].emit( ctx, start, count, v, stride ); + } + } +} + +void i810ChooseVertexState( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLuint ind = I810_XYZW_BIT|I810_RGBA_BIT; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + ind |= I810_SPEC_BIT; + + if (ctx->Fog.Enabled) + ind |= I810_FOG_BIT; + + if (ctx->Texture._EnabledUnits & 0x2) + /* unit 1 enabled */ + ind |= I810_TEX1_BIT|I810_TEX0_BIT; + else if (ctx->Texture._EnabledUnits & 0x1) + /* unit 0 enabled */ + ind |= I810_TEX0_BIT; + + imesa->SetupIndex = ind; + + if (I810_DEBUG & (DEBUG_VERTS|DEBUG_STATE)) + i810PrintSetupFlags( __FUNCTION__, ind ); + + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = i810_interp_extras; + tnl->Driver.Render.CopyPV = i810_copy_pv_extras; + } else { + tnl->Driver.Render.Interp = setup_tab[ind].interp; + tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv; + } + + if (setup_tab[ind].vertex_format != imesa->Setup[I810_CTXREG_VF]) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_VF] = setup_tab[ind].vertex_format; + imesa->vertex_size = setup_tab[ind].vertex_size; + imesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; + } +} + + + +void i810_emit_contiguous_verts( GLcontext *ctx, + GLuint start, + GLuint count ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLuint vertex_size = imesa->vertex_size * 4; + GLuint *dest = i810AllocDmaLow( imesa, (count-start) * vertex_size); + setup_tab[imesa->SetupIndex].emit( ctx, start, count, dest, vertex_size ); +} + + + +void i810InitVB( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + + imesa->verts = (GLubyte *)ALIGN_MALLOC(size * 4 * 16, 32); + + { + static int firsttime = 1; + if (firsttime) { + init_setup_tab(); + firsttime = 0; + } + } +} + + +void i810FreeVB( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + if (imesa->verts) { + ALIGN_FREE(imesa->verts); + imesa->verts = 0; + } + + if (imesa->UbyteSecondaryColor.Ptr) { + ALIGN_FREE(imesa->UbyteSecondaryColor.Ptr); + imesa->UbyteSecondaryColor.Ptr = 0; + } + + if (imesa->UbyteColor.Ptr) { + ALIGN_FREE(imesa->UbyteColor.Ptr); + imesa->UbyteColor.Ptr = 0; + } +} diff --git a/src/mesa/drivers/dri/i810/i810vb.h b/src/mesa/drivers/dri/i810/i810vb.h new file mode 100644 index 00000000000..30e58357ea8 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810vb.h @@ -0,0 +1,62 @@ +/* + * GLX Hardware Device Driver for Intel i810 + * Copyright (C) 1999 Keith Whitwell + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810vb.h,v 1.4 2002/02/22 21:33:04 dawes Exp $ */ + +#ifndef I810VB_INC +#define I810VB_INC + +#include "mtypes.h" +#include "swrast/swrast.h" + +#define _I810_NEW_VERTEX (_NEW_TEXTURE | \ + _DD_NEW_SEPARATE_SPECULAR | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _NEW_FOG) + + +extern void i810ChooseVertexState( GLcontext *ctx ); +extern void i810CheckTexSizes( GLcontext *ctx ); +extern void i810BuildVertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ); + + +extern void i810_emit_contiguous_verts( GLcontext *ctx, + GLuint start, + GLuint count ); + +extern void i810_translate_vertex( GLcontext *ctx, + const i810Vertex *src, + SWvertex *dst ); + +extern void i810InitVB( GLcontext *ctx ); +extern void i810FreeVB( GLcontext *ctx ); + +extern void i810_print_vertex( GLcontext *ctx, const i810Vertex *v ); +extern void i810PrintSetupFlags(char *msg, GLuint flags ); + +#endif diff --git a/src/mesa/drivers/dri/i810/server/i810_common.h b/src/mesa/drivers/dri/i810/server/i810_common.h new file mode 100644 index 00000000000..02e548be0ed --- /dev/null +++ b/src/mesa/drivers/dri/i810/server/i810_common.h @@ -0,0 +1,192 @@ +/* i810_common.h -- common header definitions for I810 2D/3D/DRM suite + * + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Converted to common header format: + * Jens Owen + * + * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i810_common.h,v 1.1 2002/09/11 00:29:31 dawes Exp $ + * + */ + +/* WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (i810_drm.h) + */ + +#ifndef _I810_COMMON_H_ +#define _I810_COMMON_H_ + +#ifndef _I810_DEFINES_ +#define _I810_DEFINES_ +#define I810_USE_BATCH 1 + +#define I810_DMA_BUF_ORDER 12 +#define I810_DMA_BUF_SZ (1< + * + * based on the i740 driver by + * Kevin E. Martin + * + * + */ + +#ifndef _I810_REG_H +#define _I810_REG_H + +/* I/O register offsets + */ +#define SRX 0x3C4 /* p208 */ +#define GRX 0x3CE /* p213 */ +#define ARX 0x3C0 /* p224 */ + +/* VGA Color Palette Registers */ +#define DACMASK 0x3C6 /* p232 */ +#define DACSTATE 0x3C7 /* p232 */ +#define DACRX 0x3C7 /* p233 */ +#define DACWX 0x3C8 /* p233 */ +#define DACDATA 0x3C9 /* p233 */ + +/* CRT Controller Registers (CRX) */ +#define START_ADDR_HI 0x0C /* p246 */ +#define START_ADDR_LO 0x0D /* p247 */ +#define VERT_SYNC_END 0x11 /* p249 */ +#define EXT_VERT_TOTAL 0x30 /* p257 */ +#define EXT_VERT_DISPLAY 0x31 /* p258 */ +#define EXT_VERT_SYNC_START 0x32 /* p259 */ +#define EXT_VERT_BLANK_START 0x33 /* p260 */ +#define EXT_HORIZ_TOTAL 0x35 /* p261 */ +#define EXT_HORIZ_BLANK 0x39 /* p261 */ +#define EXT_START_ADDR 0x40 /* p262 */ +#define EXT_START_ADDR_ENABLE 0x80 +#define EXT_OFFSET 0x41 /* p263 */ +#define EXT_START_ADDR_HI 0x42 /* p263 */ +#define INTERLACE_CNTL 0x70 /* p264 */ +#define INTERLACE_ENABLE 0x80 +#define INTERLACE_DISABLE 0x00 + +/* Miscellaneous Output Register + */ +#define MSR_R 0x3CC /* p207 */ +#define MSR_W 0x3C2 /* p207 */ +#define IO_ADDR_SELECT 0x01 + +#define MDA_BASE 0x3B0 /* p207 */ +#define CGA_BASE 0x3D0 /* p207 */ + +/* CR80 - IO Control, p264 + */ +#define IO_CTNL 0x80 +#define EXTENDED_ATTR_CNTL 0x02 +#define EXTENDED_CRTC_CNTL 0x01 + +/* GR10 - Address mapping, p221 + */ +#define ADDRESS_MAPPING 0x10 +#define PAGE_TO_LOCAL_MEM_ENABLE 0x10 +#define GTT_MEM_MAP_ENABLE 0x08 +#define PACKED_MODE_ENABLE 0x04 +#define LINEAR_MODE_ENABLE 0x02 +#define PAGE_MAPPING_ENABLE 0x01 + +/* Blitter control, p378 + */ +#define BITBLT_CNTL 0x7000c +#define COLEXP_MODE 0x30 +#define COLEXP_8BPP 0x00 +#define COLEXP_16BPP 0x10 +#define COLEXP_24BPP 0x20 +#define COLEXP_RESERVED 0x30 +#define BITBLT_STATUS 0x01 + +/* p375. + */ +#define DISPLAY_CNTL 0x70008 +#define VGA_WRAP_MODE 0x02 +#define VGA_WRAP_AT_256KB 0x00 +#define VGA_NO_WRAP 0x02 +#define GUI_MODE 0x01 +#define STANDARD_VGA_MODE 0x00 +#define HIRES_MODE 0x01 + +/* p375 + */ +#define PIXPIPE_CONFIG_0 0x70009 +#define DAC_8_BIT 0x80 +#define DAC_6_BIT 0x00 +#define HW_CURSOR_ENABLE 0x10 +#define EXTENDED_PALETTE 0x01 + +/* p375 + */ +#define PIXPIPE_CONFIG_1 0x7000a +#define DISPLAY_COLOR_MODE 0x0F +#define DISPLAY_VGA_MODE 0x00 +#define DISPLAY_8BPP_MODE 0x02 +#define DISPLAY_15BPP_MODE 0x04 +#define DISPLAY_16BPP_MODE 0x05 +#define DISPLAY_24BPP_MODE 0x06 +#define DISPLAY_32BPP_MODE 0x07 + +/* p375 + */ +#define PIXPIPE_CONFIG_2 0x7000b +#define DISPLAY_GAMMA_ENABLE 0x08 +#define DISPLAY_GAMMA_DISABLE 0x00 +#define OVERLAY_GAMMA_ENABLE 0x04 +#define OVERLAY_GAMMA_DISABLE 0x00 + + +/* p380 + */ +#define DISPLAY_BASE 0x70020 +#define DISPLAY_BASE_MASK 0x03fffffc + + +/* Cursor control registers, pp383-384 + */ +/* Desktop (845G, 865G) */ +#define CURSOR_CONTROL 0x70080 +#define CURSOR_ENABLE 0x80000000 +#define CURSOR_GAMMA_ENABLE 0x40000000 +#define CURSOR_STRIDE_MASK 0x30000000 +#define CURSOR_FORMAT_SHIFT 24 +#define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT) +#define CURSOR_FORMAT_2C (0x00 << CURSOR_FORMAT_SHIFT) +#define CURSOR_FORMAT_3C (0x01 << CURSOR_FORMAT_SHIFT) +#define CURSOR_FORMAT_4C (0x02 << CURSOR_FORMAT_SHIFT) +#define CURSOR_FORMAT_ARGB (0x04 << CURSOR_FORMAT_SHIFT) +#define CURSOR_FORMAT_XRGB (0x05 << CURSOR_FORMAT_SHIFT) + +/* Mobile and i810 */ +#define CURSOR_A_CONTROL CURSOR_CONTROL +#define CURSOR_ORIGIN_SCREEN 0x00 /* i810 only */ +#define CURSOR_ORIGIN_DISPLAY 0x1 /* i810 only */ +#define CURSOR_MODE 0x27 +#define CURSOR_MODE_DISABLE 0x00 +#define CURSOR_MODE_32_4C_AX 0x01 /* i810 only */ +#define CURSOR_MODE_64_3C 0x04 +#define CURSOR_MODE_64_4C_AX 0x05 +#define CURSOR_MODE_64_4C 0x06 +#define CURSOR_MODE_64_32B_AX 0x07 +#define CURSOR_MODE_64_ARGB_AX (0x20 | CURSOR_MODE_64_32B_AX) +#define MCURSOR_PIPE_SELECT (1 << 28) +#define MCURSOR_PIPE_A 0x00 +#define MCURSOR_PIPE_B (1 << 28) +#define MCURSOR_GAMMA_ENABLE (1 << 26) +#define MCURSOR_MEM_TYPE_LOCAL (1 << 25) + + +#define CURSOR_BASEADDR 0x70084 +#define CURSOR_A_BASE CURSOR_BASEADDR +#define CURSOR_BASEADDR_MASK 0x1FFFFF00 +#define CURSOR_A_POSITION 0x70088 +#define CURSOR_POS_SIGN 0x8000 +#define CURSOR_POS_MASK 0x007FF +#define CURSOR_X_SHIFT 0 +#define CURSOR_Y_SHIFT 16 +#define CURSOR_X_LO 0x70088 +#define CURSOR_X_HI 0x70089 +#define CURSOR_X_POS 0x00 +#define CURSOR_X_NEG 0x80 +#define CURSOR_Y_LO 0x7008A +#define CURSOR_Y_HI 0x7008B +#define CURSOR_Y_POS 0x00 +#define CURSOR_Y_NEG 0x80 + +#define CURSOR_A_PALETTE0 0x70090 +#define CURSOR_A_PALETTE1 0x70094 +#define CURSOR_A_PALETTE2 0x70098 +#define CURSOR_A_PALETTE3 0x7009C + +#define CURSOR_SIZE 0x700A0 +#define CURSOR_SIZE_MASK 0x3FF +#define CURSOR_SIZE_HSHIFT 0 +#define CURSOR_SIZE_VSHIFT 12 + + +/* Similar registers exist in Device 0 on the i810 (pp55-65), but I'm + * not sure they refer to local (graphics) memory. + * + * These details are for the local memory control registers, + * (pp301-310). The test machines are not equiped with local memory, + * so nothing is tested. Only a single row seems to be supported. + */ +#define DRAM_ROW_TYPE 0x3000 +#define DRAM_ROW_0 0x01 +#define DRAM_ROW_0_SDRAM 0x01 +#define DRAM_ROW_0_EMPTY 0x00 +#define DRAM_ROW_CNTL_LO 0x3001 +#define DRAM_PAGE_MODE_CTRL 0x10 +#define DRAM_RAS_TO_CAS_OVRIDE 0x08 +#define DRAM_CAS_LATENCY 0x04 +#define DRAM_RAS_TIMING 0x02 +#define DRAM_RAS_PRECHARGE 0x01 +#define DRAM_ROW_CNTL_HI 0x3002 +#define DRAM_REFRESH_RATE 0x18 +#define DRAM_REFRESH_DISABLE 0x00 +#define DRAM_REFRESH_60HZ 0x08 +#define DRAM_REFRESH_FAST_TEST 0x10 +#define DRAM_REFRESH_RESERVED 0x18 +#define DRAM_SMS 0x07 +#define DRAM_SMS_NORMAL 0x00 +#define DRAM_SMS_NOP_ENABLE 0x01 +#define DRAM_SMS_ABPCE 0x02 +#define DRAM_SMS_MRCE 0x03 +#define DRAM_SMS_CBRCE 0x04 + +/* p307 + */ +#define DPMS_SYNC_SELECT 0x5002 +#define VSYNC_CNTL 0x08 +#define VSYNC_ON 0x00 +#define VSYNC_OFF 0x08 +#define HSYNC_CNTL 0x02 +#define HSYNC_ON 0x00 +#define HSYNC_OFF 0x02 + + + +/* p317, 319 + */ +#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */ +#define VCLK2_VCO_N 0x600a +#define VCLK2_VCO_DIV_SEL 0x6012 + +#define VCLK_DIVISOR_VGA0 0x6000 +#define VCLK_DIVISOR_VGA1 0x6004 +#define VCLK_POST_DIV 0x6010 + +#define POST_DIV_SELECT 0x70 +#define POST_DIV_1 0x00 +#define POST_DIV_2 0x10 +#define POST_DIV_4 0x20 +#define POST_DIV_8 0x30 +#define POST_DIV_16 0x40 +#define POST_DIV_32 0x50 +#define VCO_LOOP_DIV_BY_4M 0x00 +#define VCO_LOOP_DIV_BY_16M 0x04 + + +/* Instruction Parser Mode Register + * - p281 + * - 2 new bits. + */ +#define INST_PM 0x20c0 +#define AGP_SYNC_PACKET_FLUSH_ENABLE 0x20 /* reserved */ +#define SYNC_PACKET_FLUSH_ENABLE 0x10 +#define TWO_D_INST_DISABLE 0x08 +#define THREE_D_INST_DISABLE 0x04 +#define STATE_VAR_UPDATE_DISABLE 0x02 +#define PAL_STIP_DISABLE 0x01 + +#define INST_DONE 0x2090 +#define INST_PS 0x20c4 + +#define MEMMODE 0x20dc + + +/* Instruction parser error register. p279 + */ +#define IPEIR 0x2088 +#define IPEHR 0x208C + + +/* General error reporting regs, p296 + */ +#define EIR 0x20B0 +#define EMR 0x20B4 +#define ESR 0x20B8 +#define IP_ERR 0x0001 +#define ERROR_RESERVED 0xffc6 + + +/* Interrupt Control Registers + * - new bits for i810 + * - new register hwstam (mask) + */ +#define HWSTAM 0x2098 /* p290 */ +#define IER 0x20a0 /* p291 */ +#define IIR 0x20a4 /* p292 */ +#define IMR 0x20a8 /* p293 */ +#define ISR 0x20ac /* p294 */ +#define HW_ERROR 0x8000 +#define SYNC_STATUS_TOGGLE 0x1000 +#define DPY_0_FLIP_PENDING 0x0800 +#define DPY_1_FLIP_PENDING 0x0400 /* not implemented on i810 */ +#define OVL_0_FLIP_PENDING 0x0200 +#define OVL_1_FLIP_PENDING 0x0100 /* not implemented on i810 */ +#define DPY_0_VBLANK 0x0080 +#define DPY_0_EVENT 0x0040 +#define DPY_1_VBLANK 0x0020 /* not implemented on i810 */ +#define DPY_1_EVENT 0x0010 /* not implemented on i810 */ +#define HOST_PORT_EVENT 0x0008 /* */ +#define CAPTURE_EVENT 0x0004 /* */ +#define USER_DEFINED 0x0002 +#define BREAKPOINT 0x0001 + + +#define INTR_RESERVED (0x6000 | \ + DPY_1_FLIP_PENDING | \ + OVL_1_FLIP_PENDING | \ + DPY_1_VBLANK | \ + DPY_1_EVENT | \ + HOST_PORT_EVENT | \ + CAPTURE_EVENT ) + +/* FIFO Watermark and Burst Length Control Register + * + * - different offset and contents on i810 (p299) (fewer bits per field) + * - some overlay fields added + * - what does it all mean? + */ +#define FWATER_BLC 0x20d8 +#define FWATER_BLC2 0x20dc +#define MM_BURST_LENGTH 0x00700000 +#define MM_FIFO_WATERMARK 0x0001F000 +#define LM_BURST_LENGTH 0x00000700 +#define LM_FIFO_WATERMARK 0x0000001F + + +/* Fence/Tiling ranges [0..7] + */ +#define FENCE 0x2000 +#define FENCE_NR 8 + +#define I830_FENCE_START_MASK 0x07f80000 + +#define FENCE_START_MASK 0x03F80000 +#define FENCE_X_MAJOR 0x00000000 +#define FENCE_Y_MAJOR 0x00001000 +#define FENCE_SIZE_MASK 0x00000700 +#define FENCE_SIZE_512K 0x00000000 +#define FENCE_SIZE_1M 0x00000100 +#define FENCE_SIZE_2M 0x00000200 +#define FENCE_SIZE_4M 0x00000300 +#define FENCE_SIZE_8M 0x00000400 +#define FENCE_SIZE_16M 0x00000500 +#define FENCE_SIZE_32M 0x00000600 +#define FENCE_SIZE_64M 0x00000700 +#define FENCE_PITCH_MASK 0x00000070 +#define FENCE_PITCH_1 0x00000000 +#define FENCE_PITCH_2 0x00000010 +#define FENCE_PITCH_4 0x00000020 +#define FENCE_PITCH_8 0x00000030 +#define FENCE_PITCH_16 0x00000040 +#define FENCE_PITCH_32 0x00000050 +#define FENCE_PITCH_64 0x00000060 +#define FENCE_VALID 0x00000001 + + +/* Registers to control page table, p274 + */ +#define PGETBL_CTL 0x2020 +#define PGETBL_ADDR_MASK 0xFFFFF000 +#define PGETBL_ENABLE_MASK 0x00000001 +#define PGETBL_ENABLED 0x00000001 + +/* Register containing pge table error results, p276 + */ +#define PGE_ERR 0x2024 +#define PGE_ERR_ADDR_MASK 0xFFFFF000 +#define PGE_ERR_ID_MASK 0x00000038 +#define PGE_ERR_CAPTURE 0x00000000 +#define PGE_ERR_OVERLAY 0x00000008 +#define PGE_ERR_DISPLAY 0x00000010 +#define PGE_ERR_HOST 0x00000018 +#define PGE_ERR_RENDER 0x00000020 +#define PGE_ERR_BLITTER 0x00000028 +#define PGE_ERR_MAPPING 0x00000030 +#define PGE_ERR_CMD_PARSER 0x00000038 +#define PGE_ERR_TYPE_MASK 0x00000007 +#define PGE_ERR_INV_TABLE 0x00000000 +#define PGE_ERR_INV_PTE 0x00000001 +#define PGE_ERR_MIXED_TYPES 0x00000002 +#define PGE_ERR_PAGE_MISS 0x00000003 +#define PGE_ERR_ILLEGAL_TRX 0x00000004 +#define PGE_ERR_LOCAL_MEM 0x00000005 +#define PGE_ERR_TILED 0x00000006 + + + +/* Page table entries loaded via mmio region, p323 + */ +#define PTE_BASE 0x10000 +#define PTE_ADDR_MASK 0x3FFFF000 +#define PTE_TYPE_MASK 0x00000006 +#define PTE_LOCAL 0x00000002 +#define PTE_MAIN_UNCACHED 0x00000000 +#define PTE_MAIN_CACHED 0x00000006 +#define PTE_VALID_MASK 0x00000001 +#define PTE_VALID 0x00000001 + + +/* Ring buffer registers, p277, overview p19 + */ +#define LP_RING 0x2030 +#define HP_RING 0x2040 + +#define RING_TAIL 0x00 +#define TAIL_ADDR 0x000FFFF8 +#define I830_TAIL_MASK 0x001FFFF8 + +#define RING_HEAD 0x04 +#define HEAD_WRAP_COUNT 0xFFE00000 +#define HEAD_WRAP_ONE 0x00200000 +#define HEAD_ADDR 0x001FFFFC +#define I830_HEAD_MASK 0x001FFFFC + +#define RING_START 0x08 +#define START_ADDR 0x00FFFFF8 +#define I830_RING_START_MASK 0xFFFFF000 + +#define RING_LEN 0x0C +#define RING_NR_PAGES 0x000FF000 +#define I830_RING_NR_PAGES 0x001FF000 +#define RING_REPORT_MASK 0x00000006 +#define RING_REPORT_64K 0x00000002 +#define RING_REPORT_128K 0x00000004 +#define RING_NO_REPORT 0x00000000 +#define RING_VALID_MASK 0x00000001 +#define RING_VALID 0x00000001 +#define RING_INVALID 0x00000000 + + + +/* BitBlt Instructions + * + * There are many more masks & ranges yet to add. + */ +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR00_OP_FULL_BLT 0x11400000 +#define BR00_OP_MONO_SRC_BLT 0x11800000 +#define BR00_OP_MONO_SRC_COPY_BLT 0x11000000 +#define BR00_OP_MONO_PAT_BLT 0x11C00000 +#define BR00_OP_MONO_SRC_COPY_IMMEDIATE_BLT (0x61 << 22) +#define BR00_OP_TEXT_IMMEDIATE_BLT 0xc000000 + + +#define BR00_TPCY_DISABLE 0x00000000 +#define BR00_TPCY_ENABLE 0x00000010 + +#define BR00_TPCY_ROP 0x00000000 +#define BR00_TPCY_NO_ROP 0x00000020 +#define BR00_TPCY_EQ 0x00000000 +#define BR00_TPCY_NOT_EQ 0x00000040 + +#define BR00_PAT_MSB_FIRST 0x00000000 /* ? */ + +#define BR00_PAT_VERT_ALIGN 0x000000e0 + +#define BR00_LENGTH 0x0000000F + +#define BR09_DEST_ADDR 0x03FFFFFF + +#define BR11_SOURCE_PITCH 0x00003FFF + +#define BR12_SOURCE_ADDR 0x03FFFFFF + +#define BR13_SOLID_PATTERN 0x80000000 +#define BR13_RIGHT_TO_LEFT 0x40000000 +#define BR13_LEFT_TO_RIGHT 0x00000000 +#define BR13_MONO_TRANSPCY 0x20000000 +#define BR13_USE_DYN_DEPTH 0x04000000 +#define BR13_DYN_8BPP 0x00000000 +#define BR13_DYN_16BPP 0x01000000 +#define BR13_DYN_24BPP 0x02000000 +#define BR13_ROP_MASK 0x00FF0000 +#define BR13_DEST_PITCH 0x0000FFFF +#define BR13_PITCH_SIGN_BIT 0x00008000 + +#define BR14_DEST_HEIGHT 0xFFFF0000 +#define BR14_DEST_WIDTH 0x0000FFFF + +#define BR15_PATTERN_ADDR 0x03FFFFFF + +#define BR16_SOLID_PAT_COLOR 0x00FFFFFF +#define BR16_BACKGND_PAT_CLR 0x00FFFFFF + +#define BR17_FGND_PAT_CLR 0x00FFFFFF + +#define BR18_SRC_BGND_CLR 0x00FFFFFF +#define BR19_SRC_FGND_CLR 0x00FFFFFF + + +/* Instruction parser instructions + */ + +#define INST_PARSER_CLIENT 0x00000000 +#define INST_OP_FLUSH 0x02000000 +#define INST_FLUSH_MAP_CACHE 0x00000001 + + +#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) + + +/* Registers in the i810 host-pci bridge pci config space which affect + * the i810 graphics operations. + */ +#define SMRAM_MISCC 0x70 +#define GMS 0x000000c0 +#define GMS_DISABLE 0x00000000 +#define GMS_ENABLE_BARE 0x00000040 +#define GMS_ENABLE_512K 0x00000080 +#define GMS_ENABLE_1M 0x000000c0 +#define USMM 0x00000030 +#define USMM_DISABLE 0x00000000 +#define USMM_TSEG_ZERO 0x00000010 +#define USMM_TSEG_512K 0x00000020 +#define USMM_TSEG_1M 0x00000030 +#define GFX_MEM_WIN_SIZE 0x00010000 +#define GFX_MEM_WIN_32M 0x00010000 +#define GFX_MEM_WIN_64M 0x00000000 + +/* Overkill? I don't know. Need to figure out top of mem to make the + * SMRAM calculations come out. Linux seems to have problems + * detecting it all on its own, so this seems a reasonable double + * check to any user supplied 'mem=...' boot param. + * + * ... unfortunately this reg doesn't work according to spec on the + * test hardware. + */ +#define WHTCFG_PAMR_DRP 0x50 +#define SYS_DRAM_ROW_0_SHIFT 16 +#define SYS_DRAM_ROW_1_SHIFT 20 +#define DRAM_MASK 0x0f +#define DRAM_VALUE_0 0 +#define DRAM_VALUE_1 8 +/* No 2 value defined */ +#define DRAM_VALUE_3 16 +#define DRAM_VALUE_4 16 +#define DRAM_VALUE_5 24 +#define DRAM_VALUE_6 32 +#define DRAM_VALUE_7 32 +#define DRAM_VALUE_8 48 +#define DRAM_VALUE_9 64 +#define DRAM_VALUE_A 64 +#define DRAM_VALUE_B 96 +#define DRAM_VALUE_C 128 +#define DRAM_VALUE_D 128 +#define DRAM_VALUE_E 192 +#define DRAM_VALUE_F 256 /* nice one, geezer */ +#define LM_FREQ_MASK 0x10 +#define LM_FREQ_133 0x10 +#define LM_FREQ_100 0x00 + + + + +/* These are 3d state registers, but the state is invarient, so we let + * the X server handle it: + */ + + + +/* GFXRENDERSTATE_COLOR_CHROMA_KEY, p135 + */ +#define GFX_OP_COLOR_CHROMA_KEY ((0x3<<29)|(0x1d<<24)|(0x2<<16)|0x1) +#define CC1_UPDATE_KILL_WRITE (1<<28) +#define CC1_ENABLE_KILL_WRITE (1<<27) +#define CC1_DISABLE_KILL_WRITE 0 +#define CC1_UPDATE_COLOR_IDX (1<<26) +#define CC1_UPDATE_CHROMA_LOW (1<<25) +#define CC1_UPDATE_CHROMA_HI (1<<24) +#define CC1_CHROMA_LOW_MASK ((1<<24)-1) +#define CC2_COLOR_IDX_SHIFT 24 +#define CC2_COLOR_IDX_MASK (0xff<<24) +#define CC2_CHROMA_HI_MASK ((1<<24)-1) + + +#define GFX_CMD_CONTEXT_SEL ((0<<29)|(0x5<<23)) +#define CS_UPDATE_LOAD (1<<17) +#define CS_UPDATE_USE (1<<16) +#define CS_UPDATE_LOAD (1<<17) +#define CS_LOAD_CTX0 0 +#define CS_LOAD_CTX1 (1<<8) +#define CS_USE_CTX0 0 +#define CS_USE_CTX1 (1<<0) + +/* I810 LCD/TV registers */ +#define LCD_TV_HTOTAL 0x60000 +#define LCD_TV_C 0x60018 +#define LCD_TV_OVRACT 0x6001C + +#define LCD_TV_ENABLE (1 << 31) +#define LCD_TV_VGAMOD (1 << 28) + +/* I830 CRTC registers */ +#define HTOTAL_A 0x60000 +#define HBLANK_A 0x60004 +#define HSYNC_A 0x60008 +#define VTOTAL_A 0x6000c +#define VBLANK_A 0x60010 +#define VSYNC_A 0x60014 +#define PIPEASRC 0x6001c +#define BCLRPAT_A 0x60020 + +#define HTOTAL_B 0x61000 +#define HBLANK_B 0x61004 +#define HSYNC_B 0x61008 +#define VTOTAL_B 0x6100c +#define VBLANK_B 0x61010 +#define VSYNC_B 0x61014 +#define PIPEBSRC 0x6101c +#define BCLRPAT_B 0x61020 + +#define DPLL_A 0x06014 +#define DPLL_B 0x06018 +#define FPA0 0x06040 +#define FPA1 0x06044 + +#define I830_HTOTAL_MASK 0xfff0000 +#define I830_HACTIVE_MASK 0x7ff + +#define I830_HBLANKEND_MASK 0xfff0000 +#define I830_HBLANKSTART_MASK 0xfff + +#define I830_HSYNCEND_MASK 0xfff0000 +#define I830_HSYNCSTART_MASK 0xfff + +#define I830_VTOTAL_MASK 0xfff0000 +#define I830_VACTIVE_MASK 0x7ff + +#define I830_VBLANKEND_MASK 0xfff0000 +#define I830_VBLANKSTART_MASK 0xfff + +#define I830_VSYNCEND_MASK 0xfff0000 +#define I830_VSYNCSTART_MASK 0xfff + +#define I830_PIPEA_HORZ_MASK 0x7ff0000 +#define I830_PIPEA_VERT_MASK 0x7ff + +#define ADPA 0x61100 +#define ADPA_DAC_ENABLE (1<<31) +#define ADPA_DAC_DISABLE 0 +#define ADPA_PIPE_SELECT_MASK (1<<30) +#define ADPA_PIPE_A_SELECT 0 +#define ADPA_PIPE_B_SELECT (1<<30) +#define ADPA_USE_VGA_HVPOLARITY (1<<15) +#define ADPA_SETS_HVPOLARITY 0 +#define ADPA_VSYNC_CNTL_DISABLE (1<<11) +#define ADPA_VSYNC_CNTL_ENABLE 0 +#define ADPA_HSYNC_CNTL_DISABLE (1<<10) +#define ADPA_HSYNC_CNTL_ENABLE 0 +#define ADPA_VSYNC_ACTIVE_HIGH (1<<4) +#define ADPA_VSYNC_ACTIVE_LOW 0 +#define ADPA_HSYNC_ACTIVE_HIGH (1<<3) +#define ADPA_HSYNC_ACTIVE_LOW 0 + + +#define DVOA 0x61120 +#define DVOB 0x61140 +#define DVOC 0x61160 +#define DVO_ENABLE (1<<31) + +#define DVOA_SRCDIM 0x61124 +#define DVOB_SRCDIM 0x61144 +#define DVOC_SRCDIM 0x61164 + +#define LVDS 0x61180 + +#define PIPEACONF 0x70008 +#define PIPEACONF_ENABLE (1<<31) +#define PIPEACONF_DISABLE 0 +#define PIPEACONF_DOUBLE_WIDE (1<<30) +#define PIPEACONF_SINGLE_WIDE 0 +#define PIPEACONF_PIPE_UNLOCKED 0 +#define PIPEACONF_PIPE_LOCKED (1<<25) +#define PIPEACONF_PALETTE 0 +#define PIPEACONF_GAMMA (1<<24) + +#define PIPEBCONF 0x71008 +#define PIPEBCONF_ENABLE (1<<31) +#define PIPEBCONF_DISABLE 0 +#define PIPEBCONF_GAMMA (1<<24) +#define PIPEBCONF_PALETTE 0 + +#define DSPACNTR 0x70180 +#define DSPBCNTR 0x71180 +#define DISPLAY_PLANE_ENABLE (1<<31) +#define DISPLAY_PLANE_DISABLE 0 +#define DISPPLANE_GAMMA_ENABLE (1<<30) +#define DISPPLANE_GAMMA_DISABLE 0 +#define DISPPLANE_PIXFORMAT_MASK (0xf<<26) +#define DISPPLANE_8BPP (0x2<<26) +#define DISPPLANE_15_16BPP (0x4<<26) +#define DISPPLANE_16BPP (0x5<<26) +#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) +#define DISPPLANE_32BPP (0x7<<26) +#define DISPPLANE_STEREO_ENABLE (1<<25) +#define DISPPLANE_STEREO_DISABLE 0 +#define DISPPLANE_SEL_PIPE_MASK (1<<24) +#define DISPPLANE_SEL_PIPE_A 0 +#define DISPPLANE_SEL_PIPE_B (1<<24) +#define DISPPLANE_SRC_KEY_ENABLE (1<<22) +#define DISPPLANE_SRC_KEY_DISABLE 0 +#define DISPPLANE_LINE_DOUBLE (1<<20) +#define DISPPLANE_NO_LINE_DOUBLE 0 +#define DISPPLANE_STEREO_POLARITY_FIRST 0 +#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) +/* plane B only */ +#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15) +#define DISPPLANE_ALPHA_TRANS_DISABLE 0 +#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0 +#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1) + +#define DSPABASE 0x70184 +#define DSPASTRIDE 0x70188 + +#define DSPBBASE 0x71184 +#define DSPBADDR DSPBBASE +#define DSPBSTRIDE 0x71188 + +/* Various masks for reserved bits, etc. */ +#define I830_FWATER1_MASK (~((1<<11)|(1<<10)|(1<<9)| \ + (1<<8)|(1<<26)|(1<<25)|(1<<24)|(1<<5)|(1<<4)|(1<<3)| \ + (1<<2)|(1<<1)|1|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16))) +#define I830_FWATER2_MASK ~(0) + +#define DV0A_RESERVED ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<16)|(1<<5)|(1<<1)|1) +#define DV0B_RESERVED ((1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<16)|(1<<5)|(1<<1)|1) +#define VGA0_N_DIVISOR_MASK ((1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)) +#define VGA0_M1_DIVISOR_MASK ((1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)) +#define VGA0_M2_DIVISOR_MASK ((1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1) +#define VGA0_M1M2N_RESERVED ~(VGA0_N_DIVISOR_MASK|VGA0_M1_DIVISOR_MASK|VGA0_M2_DIVISOR_MASK) +#define VGA0_POSTDIV_MASK ((1<<7)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1) +#define VGA1_POSTDIV_MASK ((1<<15)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)) +#define VGA_POSTDIV_RESERVED ~(VGA0_POSTDIV_MASK|VGA1_POSTDIV_MASK|(1<<7)|(1<<15)) +#define DPLLA_POSTDIV_MASK ((1<<23)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)) +#define DPLLA_RESERVED ((1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<22)|(1<<15)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1) +#define ADPA_RESERVED ((1<<2)|(1<<1)|1|(1<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)) +#define SUPER_WORD 32 +#define BURST_A_MASK ((1<<11)|(1<<10)|(1<<9)|(1<<8)) +#define BURST_B_MASK ((1<<26)|(1<<25)|(1<<24)) +#define WATER_A_MASK ((1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|1) +#define WATER_B_MASK ((1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)) +#define WATER_RESERVED ((1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<23)|(1<<22)|(1<<21)|(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<7)|(1<<6)) +#define PIPEACONF_RESERVED ((1<<29)|(1<<28)|(1<<27)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)|0xffff) +#define PIPEBCONF_RESERVED ((1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<23)|(1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16)|0xffff) +#define DSPACNTR_RESERVED ((1<<23)|(1<<19)|(1<<17)|(1<<16)|0xffff) +#define DSPBCNTR_RESERVED ((1<<23)|(1<<19)|(1<<17)|(1<<16)|0x7ffe) + +#define I830_GMCH_CTRL 0x52 + +#define I830_GMCH_ENABLED 0x4 +#define I830_GMCH_MEM_MASK 0x1 +#define I830_GMCH_MEM_64M 0x1 +#define I830_GMCH_MEM_128M 0 + +#define I830_GMCH_GMS_MASK 0x70 +#define I830_GMCH_GMS_DISABLED 0x00 +#define I830_GMCH_GMS_LOCAL 0x10 +#define I830_GMCH_GMS_STOLEN_512 0x20 +#define I830_GMCH_GMS_STOLEN_1024 0x30 +#define I830_GMCH_GMS_STOLEN_8192 0x40 + +#define I830_RDRAM_CHANNEL_TYPE 0x03010 +#define I830_RDRAM_ND(x) (((x) & 0x20) >> 5) +#define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3) + +#define I855_GMCH_GMS_MASK (0x7 << 4) +#define I855_GMCH_GMS_DISABLED 0x00 +#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) +#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) +#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) +#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) +#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) + +#define I85X_CAPID 0x44 +#define I85X_VARIANT_MASK 0x7 +#define I85X_VARIANT_SHIFT 5 +#define I855_GME 0x0 +#define I855_GM 0x4 +#define I852_GME 0x2 +#define I852_GM 0x5 + +/* BLT commands */ +#define COLOR_BLT_CMD ((2<<29)|(0x40<<22)|(0x3)) +#define COLOR_BLT_WRITE_ALPHA (1<<21) +#define COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|(0x4)) +#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) +#define XY_COLOR_BLT_WRITE_RGB (1<<20) + +#define XY_SETUP_CLIP_BLT_CMD ((2<<29)|(3<<22)|1) + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) +#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|0x4) +#define SRC_COPY_BLT_WRITE_ALPHA (1<<21) +#define SRC_COPY_BLT_WRITE_RGB (1<<20) + +#define XY_MONO_PAT_BLT_CMD ((0x2<<29)|(0x52<<22)|0x7) +#define XY_MONO_PAT_VERT_SEED ((1<<10)|(1<<9)|(1<<8)) +#define XY_MONO_PAT_HORT_SEED ((1<<14)|(1<<13)|(1<<12)) +#define XY_MONO_PAT_BLT_WRITE_ALPHA (1<<21) +#define XY_MONO_PAT_BLT_WRITE_RGB (1<<20) + +#define XY_MONO_SRC_BLT_CMD ((0x2<<29)|(0x54<<22)|(0x6)) +#define XY_MONO_SRC_BLT_WRITE_ALPHA (1<<21) +#define XY_MONO_SRC_BLT_WRITE_RGB (1<<20) + +/* 3d state */ +#define STATE3D_FOG_MODE ((3<<29)|(0x1d<<24)|(0x89<<16)|2) +#define FOG_MODE_VERTEX (1<<31) +#define STATE3D_MAP_COORD_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8c<<16)) +#define DISABLE_TEX_TRANSFORM (1<<28) +#define TEXTURE_SET(x) (x<<29) +#define STATE3D_RASTERIZATION_RULES ((3<<29)|(0x07<<24)) +#define POINT_RASTER_ENABLE (1<<15) +#define POINT_RASTER_OGL (1<<13) +#define STATE3D_VERTEX_TRANSFORM ((3<<29)|(0x1d<<24)|(0x8b<<16)) +#define DISABLE_VIEWPORT_TRANSFORM (1<<31) +#define DISABLE_PERSPECTIVE_DIVIDE (1<<29) + +#define MI_SET_CONTEXT (0x18<<23) +#define CTXT_NO_RESTORE (1) +#define CTXT_PALETTE_SAVE_DISABLE (1<<3) +#define CTXT_PALETTE_RESTORE_DISABLE (1<<2) + +/* Dword 0 */ +#define MI_VERTEX_BUFFER (0x17<<23) +#define MI_VERTEX_BUFFER_IDX(x) (x<<20) +#define MI_VERTEX_BUFFER_PITCH(x) (x<<13) +#define MI_VERTEX_BUFFER_WIDTH(x) (x<<6) +/* Dword 1 */ +#define MI_VERTEX_BUFFER_DISABLE (1) + +/* Overlay Flip */ +#define MI_OVERLAY_FLIP (0x11<<23) +#define MI_OVERLAY_FLIP_CONTINUE (0<<21) +#define MI_OVERLAY_FLIP_ON (1<<21) +#define MI_OVERLAY_FLIP_OFF (2<<21) + +/* Wait for Events */ +#define MI_WAIT_FOR_EVENT (0x03<<23) +#define MI_WAIT_FOR_OVERLAY_FLIP (1<<16) + +/* Flush */ +#define MI_FLUSH (0x04<<23) +#define MI_WRITE_DIRTY_STATE (1<<4) +#define MI_END_SCENE (1<<3) +#define MI_INHIBIT_RENDER_CACHE_FLUSH (1<<2) +#define MI_INVALIDATE_MAP_CACHE (1<<0) + +/* Noop */ +#define MI_NOOP 0x00 +#define MI_NOOP_WRITE_ID (1<<22) +#define MI_NOOP_ID_MASK (1<<22 - 1) + +#define STATE3D_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x01<<16)) + +/* STATE3D_FOG_MODE stuff */ +#define ENABLE_FOG_SOURCE (1<<27) +#define ENABLE_FOG_CONST (1<<24) +#define ENABLE_FOG_DENSITY (1<<23) + + +#define MAX_DISPLAY_PIPES 2 + +typedef enum { + CrtIndex = 0, + TvIndex, + DfpIndex, + LfpIndex, + Tv2Index, + Dfp2Index, + UnknownIndex, + Unknown2Index, + NumDisplayTypes, + NumKnownDisplayTypes = UnknownIndex +} DisplayType; + +/* What's connected to the pipes (as reported by the BIOS) */ +#define PIPE_ACTIVE_MASK 0xff +#define PIPE_CRT_ACTIVE (1 << CrtIndex) +#define PIPE_TV_ACTIVE (1 << TvIndex) +#define PIPE_DFP_ACTIVE (1 << DfpIndex) +#define PIPE_LCD_ACTIVE (1 << LfpIndex) +#define PIPE_TV2_ACTIVE (1 << Tv2Index) +#define PIPE_DFP2_ACTIVE (1 << Dfp2Index) +#define PIPE_UNKNOWN_ACTIVE ((1 << UnknownIndex) | \ + (1 << Unknown2Index)) + +#define PIPE_SIZED_DISP_MASK (PIPE_DFP_ACTIVE | \ + PIPE_LCD_ACTIVE | \ + PIPE_DFP2_ACTIVE) + +#define PIPE_A_SHIFT 0 +#define PIPE_B_SHIFT 8 +#define PIPE_SHIFT(n) ((n) == 0 ? \ + PIPE_A_SHIFT : PIPE_B_SHIFT) + +/* + * Some BIOS scratch area registers. The 845 (and 830?) store the amount + * of video memory available to the BIOS in SWF1. + */ + +#define SWF0 0x71410 +#define SWF1 0x71414 +#define SWF2 0x71418 +#define SWF3 0x7141c +#define SWF4 0x71420 +#define SWF5 0x71424 +#define SWF6 0x71428 + +/* + * 855 scratch registers. + */ +#define SWF00 0x70410 +#define SWF01 0x70414 +#define SWF02 0x70418 +#define SWF03 0x7041c +#define SWF04 0x70420 +#define SWF05 0x70424 +#define SWF06 0x70428 + +#define SWF10 SWF0 +#define SWF11 SWF1 +#define SWF12 SWF2 +#define SWF13 SWF3 +#define SWF14 SWF4 +#define SWF15 SWF5 +#define SWF16 SWF6 + +#define SWF30 0x72414 +#define SWF31 0x72418 +#define SWF32 0x7241c + +/* + * Overlay registers. These are overlay registers accessed via MMIO. + * Those loaded via the overlay register page are defined in i830_video.c. + */ +#define OVADD 0x30000 + +#define DOVSTA 0x30008 +#define OC_BUF (0x3<<20) + +#define OGAMC5 0x30010 +#define OGAMC4 0x30014 +#define OGAMC3 0x30018 +#define OGAMC2 0x3001c +#define OGAMC1 0x30020 +#define OGAMC0 0x30024 + + +/* + * Palette registers + */ +#define PALETTE_A 0x0a000 +#define PALETTE_B 0x0a800 + +#endif /* _I810_REG_H */