diff options
Diffstat (limited to 'src/mesa')
21 files changed, 10537 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/savage/savage_3d_reg.h b/src/mesa/drivers/dri/savage/savage_3d_reg.h new file mode 100644 index 0000000000..b56a9004f3 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savage_3d_reg.h @@ -0,0 +1,1063 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#ifndef SAVAGE_3D_REG_H +#define SAVAGE_3D_REG_H + +#define uint32 unsigned long +#define uint16 unsigned short + +#define VIDEO_MEM_ADR 0x02 +#define SYSTEM_MEM_ADR 0x01 +#define AGP_MEM_ADR 0x03 + +/*********************************************************** + + ----------- 3D ENGINE UNIT Registers ------------- + + *********************************************************/ + +typedef union +{ + struct + { + unsigned int reserved : 4; + unsigned int ofs : 28; + }ni; + unsigned int ui; +} Reg_ZPixelOffset; + +typedef union +{ + /* This reg exists only on Savage4. */ + struct + { + unsigned int cmpFunc : 3; + unsigned int stencilEn : 1; + unsigned int readMask : 8; + unsigned int writeMask : 8; + unsigned int failOp : 3; + unsigned int passZfailOp : 3; + unsigned int passZpassOp : 3; + unsigned int reserved : 3; + }ni; + unsigned int ui; +} Reg_StencilCtrl; + +/************************** + Texture Registers +**************************/ +typedef union +{ + /* The layout of this reg differs between Savage4 and Savage3D. */ + struct + { + unsigned int tex0Width : 4; + unsigned int tex0Height : 4; + unsigned int tex0Fmt : 4; + unsigned int tex1Width : 4; + unsigned int tex1Height : 4; + unsigned int tex1Fmt : 4; + unsigned int texBLoopEn : 1; + unsigned int tex0En : 1; + unsigned int tex1En : 1; + unsigned int orthProjEn : 1; + unsigned int reserved : 1; + unsigned int palSize : 2; + unsigned int newPal : 1; + }s4; + struct + { + unsigned int texWidth : 4; + unsigned int reserved1 : 4; + unsigned int texHeight : 4; + unsigned int reserved2 : 4; + /* Savage3D supports only the first 8 texture formats defined in + enum TexFmt in savge_bci.h. */ + unsigned int texFmt : 3; + unsigned int palSize : 2; + unsigned int reserved3 : 10; + unsigned int newPal : 1; + }s3d; + unsigned int ui; +} Reg_TexDescr; + +typedef union +{ + /* The layout of this reg is the same on Savage4 and Savage3D, + but the Savage4 has two of them, Savage3D has only one. */ + struct + { + unsigned int inSysTex : 1; + unsigned int inAGPTex : 1; + unsigned int reserved : 1; + unsigned int addr : 29; + }ni; + unsigned int ui; +} Reg_TexAddr; + +typedef union +{ + /* The layout of this reg is the same on Savage4 and Savage3D, + but the Savage4 has two of them, Savage3D has only one. */ + struct + { + unsigned int reserved : 3; + unsigned int addr : 29; + }ni; + unsigned int ui; +} Reg_TexPalAddr; + +typedef union +{ + /* The layout of this reg on Savage4 and Savage3D are very similar. */ + struct + { + unsigned int xprClr0 : 16; + unsigned int xprClr1 : 16; /* this is reserved on Savage3D */ + }ni; + unsigned int ui; +} Reg_TexXprClr; /* transparency color in RGB565 format*/ + +typedef union +{ + /* The layout of this reg differs between Savage4 and Savage3D. + * Savage4 has two of them, Savage3D has only one. */ + struct + { + unsigned int filterMode : 2; + unsigned int mipmapEnable : 1; + unsigned int dBias : 9; + unsigned int dMax : 4; + unsigned int uMode : 2; + unsigned int vMode : 2; + unsigned int useDFraction : 1; + unsigned int texXprEn : 1; + unsigned int clrBlendAlphaSel : 2; + unsigned int clrArg1CopyAlpha : 1; + unsigned int clrArg2CopyAlpha : 1; + unsigned int clrArg1Invert : 1; + unsigned int clrArg2Invert : 1; + unsigned int alphaBlendAlphaSel : 2; + unsigned int alphaArg1Invert : 1; + unsigned int alphaArg2Invert : 1; + }s4; + struct + { + unsigned int filterMode : 2; + unsigned int mipmapDisable : 1; + unsigned int dBias : 9; + unsigned int uWrapEn : 1; + unsigned int vWrapEn : 1; + unsigned int wrapMode : 2; + unsigned int texEn : 1; + unsigned int useDFraction : 1; + unsigned int reserved1 : 1; + /* Color Compare Alpha Blend Control + 0 - reduce dest alpha to 0 or 1 + 1 - blend with destination + The Utah-Driver doesn't know how to use it and sets it to 0. */ + unsigned int CCA : 1; + unsigned int texXprEn : 1; + unsigned int reserved2 : 11; + }s3d; + unsigned int ui; +} Reg_TexCtrl; + +typedef union +{ + /* This reg exists only on Savage4. */ + struct + { + unsigned int colorArg1Sel : 2; + unsigned int colorArg2Sel : 3; + unsigned int colorInvAlphaEn : 1; + unsigned int colorInvArg2En : 1; + unsigned int colorPremodSel : 1; + unsigned int colorMod1Sel : 1; + unsigned int colorMod2Sel : 2; + unsigned int colorAddSel : 2; + unsigned int colorDoBlend : 1; + unsigned int colorDo2sCompl : 1; + unsigned int colorAddBiasEn : 1; + unsigned int alphaArg1Sel : 2; + unsigned int alphaArg2Sel : 3; + unsigned int alphaMod1Sel : 1; + unsigned int alphaMod2Sel : 2; + unsigned int alphaAdd0Sel : 1; + unsigned int alphaDoBlend : 1; + unsigned int alphaDo2sCompl : 1; + unsigned int colorStageClamp : 1; + unsigned int alphaStageClamp : 1; + unsigned int colorDoDiffMul : 1; + unsigned int LeftShiftVal : 2; + }ni; + unsigned int ui; +} Reg_TexBlendCtrl; + +typedef union +{ + /* This reg exists only on Savage4. */ + struct + { + unsigned int blue : 8; + unsigned int green : 8; + unsigned int red : 8; + unsigned int alpha : 8; + }ni; + unsigned int ui; +} Reg_TexBlendColor; + +/******************************** + Tiled Surface Registers +**********************************/ + +typedef union +{ + struct + { + unsigned int frmBufOffset : 13; + unsigned int reserved : 12; + unsigned int widthInTile : 6; + unsigned int bitPerPixel : 1; + }ni; + unsigned int ui; +} Reg_TiledSurface; + +/******************************** + Draw/Shading Control Registers +**********************************/ + +typedef union +{ + /* This reg exists only on Savage4. */ + struct + { + unsigned int scissorXStart : 11; + unsigned int DPerfAccelEn : 1; + unsigned int scissorYStart : 12; + unsigned int alphaRefVal : 8; + }ni; + unsigned int ui; +} Reg_DrawCtrl0; + +typedef union +{ + /* This reg exists only on Savage4. */ + struct + { + unsigned int scissorXEnd : 11; + unsigned int XYOffsetEn : 1; + unsigned int scissorYEnd : 12; + unsigned int ditherEn : 1; + unsigned int nonNormTexCoord : 1; + unsigned int cullMode : 2; + unsigned int alphaTestCmpFunc : 3; + unsigned int alphaTestEn : 1; + }ni; + unsigned int ui; +} Reg_DrawCtrl1; + +typedef union +{ + /* This reg exists only on Savage4. */ + struct + { + unsigned int dstAlphaMode : 3; + unsigned int DstMinusSrc : 1; + unsigned int srcAlphaMode : 3; + unsigned int binaryFinalAlpha : 1; + unsigned int dstAlphaModeHighBit : 1; + unsigned int srcAlphaModeHighBit : 1; + unsigned int reserved1 : 15; + unsigned int wrZafterAlphaTst : 1; + unsigned int drawUpdateEn : 1; + unsigned int zUpdateEn : 1; + unsigned int flatShadeEn : 1; + unsigned int specShadeEn : 1; + unsigned int flushPdDestWrites : 1; + unsigned int flushPdZbufWrites : 1; + }ni; + unsigned int ui; +} Reg_DrawLocalCtrl; + +typedef union +{ + /* This reg exists only on Savage3D. */ + struct + { + unsigned int ditherEn : 1; + unsigned int XYOffsetEn : 1; + unsigned int cullMode : 2; + unsigned int vertexCountReset : 1; + unsigned int flatShadeEn : 1; + unsigned int specShadeEn : 1; + unsigned int dstAlphaMode : 3; + unsigned int srcAlphaMode : 3; + unsigned int reserved1 : 1; + unsigned int alphaTestCmpFunc : 3; + unsigned int alphaTestEn : 1; + unsigned int alphaRefVal : 8; + unsigned int texBlendCtrl : 3; + unsigned int flushPdDestWrites : 1; + unsigned int flushPdZbufWrites : 1; + /* havn't found an equivalent for Savage4. Utah-driver sets it to 0. */ + unsigned int interpMode : 1; + }ni; + unsigned int ui; +} Reg_DrawCtrl; + +#define SAVAGETBC_DECAL_S3D 0 +#define SAVAGETBC_MODULATE_S3D 1 +#define SAVAGETBC_DECALALPHA_S3D 2 +#define SAVAGETBC_MODULATEALPHA_S3D 3 +#define SAVAGETBC_4_S3D 4 +#define SAVAGETBC_5_S3D 5 +#define SAVAGETBC_COPY_S3D 6 +#define SAVAGETBC_7_S3D 7 + +typedef union +{ + /* This reg exists only on Savage3D. */ + struct + { + unsigned int scissorXStart : 11; + unsigned int reserved1 : 5; + unsigned int scissorYStart : 11; + unsigned int reserved2 : 5; + } ni; + unsigned int ui; +} Reg_ScissorsStart; + +typedef union +{ + /* This reg exists only on Savage3D. */ + struct + { + unsigned int scissorXEnd : 11; + unsigned int reserved1 : 5; + unsigned int scissorYEnd : 11; + unsigned int reserved2 : 5; + } ni; + unsigned int ui; +} Reg_ScissorsEnd; + +/******************************** + Address Registers +**********************************/ + +typedef union +{ + /* I havn't found a Savage3D equivalent of this reg in the Utah-driver. + * But Tim Roberts claims that the Savage3D supports DMA vertex and + * command buffers. */ + struct + { + unsigned int isSys : 1; + unsigned int isAGP : 1; + unsigned int reserved : 1; + unsigned int addr : 29; /*quad word aligned*/ + }ni; + unsigned int ui; +} Reg_VertBufAddr; + +typedef union +{ + /* I havn't found a Savage3D equivalent of this reg in the Utah-driver. + * But Tim Roberts claims that the Savage3D supports DMA vertex and + * command buffers. */ + struct + { + unsigned int isSys : 1; + unsigned int isAGP : 1; + unsigned int reserved : 1; + unsigned int addr : 29; /*4-quad word aligned*/ + }ni; + unsigned int ui; +} Reg_DMABufAddr; + +/******************************** + H/W Debug Registers +**********************************/ +typedef union +{ + /* The layout of this reg is the same on Savage4 and Savage3D. */ + struct + { + unsigned int y01 : 1; + unsigned int y12 : 1; + unsigned int y20 : 1; + unsigned int u01 : 1; + unsigned int u12 : 1; + unsigned int u20 : 1; + unsigned int v01 : 1; + unsigned int v12 : 1; + unsigned int v20 : 1; + unsigned int cullEn : 1; + unsigned int cullOrient : 1; + unsigned int loadNewTex : 1; + unsigned int loadNewPal : 1; + unsigned int doDSetup : 1; + unsigned int reserved : 17; + unsigned int kickOff : 1; + }ni; + unsigned int ui; +} Reg_Flag; + +/******************************** + Z Buffer Registers -- Global +**********************************/ + +typedef union +{ + /* The layout of this reg differs between Savage4 and Savage3D. */ + struct + { + unsigned int zCmpFunc : 3; + unsigned int reserved1 : 2; + unsigned int zBufEn : 1; + unsigned int reserved2 : 1; + unsigned int zExpOffset : 8; + unsigned int reserved3 : 1; + unsigned int stencilRefVal : 8; + unsigned int autoZEnable : 1; + unsigned int frameID : 1; + unsigned int reserved4 : 4; + unsigned int floatZEn : 1; + unsigned int wToZEn : 1; + }s4; + struct { + unsigned int zCmpFunc : 3; + unsigned int drawUpdateEn : 1; + unsigned int zUpdateEn : 1; + unsigned int zBufEn : 1; + unsigned int reserved1 : 2; + unsigned int zExpOffset : 8; + unsigned int wrZafterAlphaTst : 1; + unsigned int reserved2 : 15; + }s3d; + GLuint ui; +}Reg_ZBufCtrl; + +typedef union +{ + /* The layout of this reg on Savage4 and Savage3D are very similar. */ + struct + { + /* In the Utah-Driver the offset is defined as 13-bit, 2k-aligned. */ + unsigned int offset : 14; + unsigned int reserved : 11; /* 12-bits in Utah-driver */ + unsigned int zBufWidthInTiles : 6; + unsigned int zDepthSelect : 1; + }ni; + unsigned int ui; +} Reg_ZBufOffset; + +typedef union +{ + /* The layout of this reg is the same on Savage4 and Savage3D. */ + struct + { + unsigned int rLow : 6; + unsigned int reserved1 : 2; + unsigned int rHigh : 6; + unsigned int reserved2 : 2; + unsigned int wLow : 6; + unsigned int reserved3 : 2; + unsigned int wHigh : 6; + unsigned int reserved4 : 2; + }ni; + unsigned int ui; +} Reg_ZWatermarks; + +/******************************** + Fog Registers -- Global +**********************************/ +typedef union +{ + /* The layout of this reg is the same on Savage4 and Savage3D. */ + struct + { + unsigned int fogClr : 24; + unsigned int expShift : 3; + unsigned int reserved : 1; + unsigned int fogEn : 1; + unsigned int fogMode : 1; + unsigned int fogEndShift : 2; + }ni; + unsigned int ui; +}Reg_FogCtrl; + +typedef struct +{ + /* According to the Utah-driver the fog table has 64 entries on + Savage3D. Savage4 uses only 32 entries. */ + union + { + unsigned char ucEntry[64]; + uint32 ulEntry[16]; + }ni; +} Reg_FogTable; + +/*not in spec, but tempo for pp and driver*/ +typedef union +{ + struct + { + unsigned int fogDensity : 16; + unsigned int fogStart : 16; + }ni; + unsigned int ui; +}Reg_FogParam; + +/************************************** + Destination Buffer Registers -- Global +***************************************/ + +typedef union +{ + /* The layout of this reg on Savage4 and Savage3D are very similar. */ + struct + { + unsigned int dstWidthInTile : 7; + unsigned int reserved : 1; + /* In the Utah-Driver the offset is defined as 13-bit, 2k-aligned. */ + unsigned int offset : 14; + unsigned int reserved1 : 7; + /* antiAliasMode does not exist in the Utah-driver. But it includes the + * high bit of this in the destPixFmt. However, only values 0 and 2 + * are used as dstPixFmt, so antiAliasMode is effectively always 0 + * in the Utah-driver. In other words, treat as reserved on SavageIX.*/ + unsigned int antiAliasMode : 2; + unsigned int dstPixFmt : 1; + }ni; + unsigned int ui; +}Reg_DestCtrl; + +typedef union +{ + /* The layout of this reg on Savage4 and Savage3D are very similar. */ + struct + { + unsigned int destReadLow : 6; + unsigned int destReadHigh : 6; + unsigned int destWriteLow : 6; + unsigned int destWriteHigh : 6; + unsigned int texRead : 4; + unsigned int reserved4 : 2; + /* The Utah-driver calls this pixel FIFO length: + * 00 - 240, 01 - 180, 10 - 120, 11 - 60 + * However, it is not used in either driver. */ + unsigned int destFlush : 2; + }ni; + unsigned int ui; +}Reg_DestTexWatermarks; + +typedef struct _REGISTERS_ +{ + union + { + struct + { + unsigned int fDrawLocalCtrlChanged : 1; + unsigned int fTexPalAddrChanged : 1; + unsigned int fTex0CtrlChanged : 1; + unsigned int fTex1CtrlChanged : 1; + + unsigned int fTex0AddrChanged : 1; + unsigned int fTex1AddrChanged : 1; + unsigned int fTex0BlendCtrlChanged : 1; + unsigned int fTex1BlendCtrlChanged : 1; + + unsigned int fTexXprClrChanged : 1; + unsigned int fTexDescrChanged : 1; + unsigned int fFogTableChanged : 1; + unsigned int fFogCtrlChanged : 1; + + unsigned int fStencilCtrlChanged : 1; + unsigned int fZBufCtrlChanged : 1; + unsigned int fZBufOffsetChanged : 1; + unsigned int fDestCtrlChanged : 1; + + unsigned int fDrawCtrl0Changed : 1; + unsigned int fDrawCtrl1Changed : 1; + unsigned int fZWatermarksChanged : 1; + unsigned int fDestTexWatermarksChanged : 1; + + unsigned int fTexBlendColorChanged : 1; + unsigned int fDrawCtrlChanged : 1; + unsigned int fScissorsStartChanged : 1; + unsigned int fScissorsEndChanged : 1; + + unsigned int fScissorsChanged : 1; /* doesn't correspond to + a real register. */ + + unsigned int fReserved : 7; + }ni; + GLuint uiRegistersChanged; + }changed; + + Reg_DrawLocalCtrl DrawLocalCtrl; /* Savage4 only */ + + Reg_TexPalAddr TexPalAddr; + Reg_TexCtrl TexCtrl[2]; /* Savage3D uses only one */ + Reg_TexAddr TexAddr[2]; /* Savage3D uses only one */ + Reg_TexBlendCtrl TexBlendCtrl[2]; /* Savage4 only */ + + Reg_TexXprClr TexXprClr; + Reg_TexDescr TexDescr; + + Reg_FogTable FogTable; /* Savage4 uses only 32 entries */ + + Reg_FogCtrl FogCtrl; + + Reg_StencilCtrl StencilCtrl; /* Savage4 only */ + Reg_ZBufCtrl ZBufCtrl; + Reg_ZBufOffset ZBufOffset; + Reg_DestCtrl DestCtrl; + Reg_DrawCtrl0 DrawCtrl0; /* Savage4 only */ + Reg_DrawCtrl1 DrawCtrl1; /* Savage4 only */ + Reg_ZWatermarks ZWatermarks; + Reg_DestTexWatermarks DestTexWatermarks; + Reg_TexBlendColor TexBlendColor; /* Savage4 only */ + + Reg_DrawCtrl DrawCtrl; /* Savage3D only */ + Reg_ScissorsStart ScissorsStart; /* Savage3D only */ + Reg_ScissorsEnd ScissorsEnd; /* Savage3D only */ +} REGISTERS; + +/* All registers that affect textures */ +#define SAVAGE_TEXTURE_CHANGED 0x000002FE +/* Engine must be idle when global registers are changed */ +#define SAVAGE_GLOBAL_CHANGED 0x00FFFC00 + +/* Savage4/Twister/ProSavage register BCI addresses */ +#define SAVAGE_DRAWLOCALCTRL_S4 0x1e +#define SAVAGE_TEXPALADDR_S4 0x1f +#define SAVAGE_TEXCTRL0_S4 0x20 +#define SAVAGE_TEXCTRL1_S4 0x21 +#define SAVAGE_TEXADDR0_S4 0x22 +#define SAVAGE_TEXADDR1_S4 0x23 +#define SAVAGE_TEXBLEND0_S4 0x24 +#define SAVAGE_TEXBLEND1_S4 0x25 +#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */ +#define SAVAGE_TEXDESCR_S4 0x27 +#define SAVAGE_FOGTABLE_S4 0x28 +#define SAVAGE_FOGCTRL_S4 0x30 +#define SAVAGE_STENCILCTRL_S4 0x31 +#define SAVAGE_ZBUFCTRL_S4 0x32 +#define SAVAGE_ZBUFOFF_S4 0x33 +#define SAVAGE_DESTCTRL_S4 0x34 +#define SAVAGE_DRAWCTRLGLOBAL0_S4 0x35 +#define SAVAGE_DRAWCTRLGLOBAL1_S4 0x36 +#define SAVAGE_ZWATERMARK_S4 0x37 +#define SAVAGE_DESTTEXRWWATERMARK_S4 0x38 +#define SAVAGE_TEXBLENDCOLOR_S4 0x39 +/* Savage3D/MX/IC register BCI addresses */ +#define SAVAGE_TEXPALADDR_S3D 0x18 +#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */ +#define SAVAGE_TEXADDR_S3D 0x1A +#define SAVAGE_TEXDESCR_S3D 0x1B +#define SAVAGE_TEXCTRL_S3D 0x1C +#define SAVAGE_FOGTABLE_S3D 0x20 +#define SAVAGE_FOGCTRL_S3D 0x30 +#define SAVAGE_DRAWCTRL_S3D 0x31 +#define SAVAGE_ZBUFCTRL_S3D 0x32 +#define SAVAGE_ZBUFOFF_S3D 0x33 +#define SAVAGE_DESTCTRL_S3D 0x34 +#define SAVAGE_SCSTART_S3D 0x35 +#define SAVAGE_SCEND_S3D 0x36 +#define SAVAGE_ZWATERMARK_S3D 0x37 +#define SAVAGE_DESTTEXRWWATERMARK_S3D 0x38 + +#define DV_PF_555 (0x1<<8) +#define DV_PF_565 (0x2<<8) +#define DV_PF_8888 (0x4<<8) + +#define SAVAGEPACKCOLORA4L4(l,a) \ + ((l >> 4) | (a & 0xf0)) + +#define SAVAGEPACKCOLOR4444(r,g,b,a) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +#define SAVAGEPACKCOLOR1555(r,g,b,a) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define SAVAGEPACKCOLOR8888(r,g,b,a) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +#define SAVAGEPACKCOLOR565(r,g,b) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + + + +/*AlphaFunc*/ +#define LCS_A_NEVER 0x0200 +#define LCS_A_LESS 0x0201 +#define LCS_A_EQUAL 0x0202 +#define LCS_A_LEQUAL 0x0203 +#define LCS_A_GREATER 0x0204 +#define LCS_A_NOTEQUAL 0x0205 +#define LCS_A_GEQUAL 0x0206 +#define LCS_A_ALWAYS 0x0207 +/*stencilFunc*/ +#define LCS_S_NEVER 0x0200 +#define LCS_S_LESS 0x0201 +#define LCS_S_EQUAL 0x0202 +#define LCS_S_LEQUAL 0x0203 +#define LCS_S_GREATER 0x0204 +#define LCS_S_NOTEQUAL 0x0205 +#define LCS_S_GEQUAL 0x0206 +#define LCS_S_ALWAYS 0x0207 +/*depthFunc*/ + +#define LCS_Z_NEVER 0x0200 +#define LCS_Z_LESS 0x0201 +#define LCS_Z_EQUAL 0x0202 +#define LCS_Z_LEQUAL 0x0203 +#define LCS_Z_GREATER 0x0204 +#define LCS_Z_NOTEQUAL 0x0205 +#define LCS_Z_GEQUAL 0x0206 +#define LCS_Z_ALWAYS 0x0207 +#if 0 +#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) + +#endif + +/*#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24))*/ +#define PR_TRIANGLES (0x0<<18) +/*#define PR_TRISTRIP_0 (0x1<<18)*/ +/*#define PR_TRISTRIP_1 (0x2<<18)*/ +/*#define PR_TRIFAN (0x3<<18)*/ +#define PR_POLYGON (0x4<<18) +#define PR_LINES (0x5<<18) +/*#define PR_LINESTRIP (0x6<<18)*/ +/*#define PR_RECTS (0x7<<18)*/ + +/* 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) + +#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) + +#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) + +#define SAVAGE_VFMT_T0 (GFX_OP_VERTEX_FMT | \ + VF_TEXCOORD_COUNT_1 | \ + VF_SPEC_FOG_ENABLE | \ + VF_RGBA_ENABLE | \ + VF_XYZW) + +#define SAVAGE_VFMT_T0T1 (GFX_OP_VERTEX_FMT | \ + VF_TEXCOORD_COUNT_2 | \ + VF_SPEC_FOG_ENABLE | \ + VF_RGBA_ENABLE | \ + VF_XYZW) + +#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) + +/* Master data transfer engine */ +#define MDT_SRCADD_ALIGMENT (~0x1fUL) +#define MDT_SRC_PCI 0x1 +#define MDT_SRC_AGP 0x3 +#endif + + diff --git a/src/mesa/drivers/dri/savage/savage_bci.h b/src/mesa/drivers/dri/savage/savage_bci.h new file mode 100644 index 0000000000..adaf579a91 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savage_bci.h @@ -0,0 +1,741 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#ifndef SAVAGE_BCI_H +#define SAVAGE_BCI_H +/*********************** + 3D and 2D command +************************/ + +typedef enum { + AMO_BurstCmdData= 0x01010000, + AMO_3DReg= 0x01048500, + AMO_MotionCompReg= 0x01048900, + AMO_VideoEngUnit= 0x01048A00, + AMO_CmdBufAddr= 0x01048c14, + AMO_TiledSurfReg0= 0x01048C40, + AMO_TiledSurfReg1= 0x01048C44, + AMO_TiledSurfReg2= 0x01048C48, + AMO_TiledSurfReg3= 0x01048C4C, + AMO_TiledSurfReg4= 0x01048C50, + AMO_TiledSurfReg5= 0x01048C54, + AMO_TiledSurfReg6= 0x01048C58, + AMO_TiledSurfReg7= 0x01048C5C, + AMO_LPBModeReg= 0x0100FF00, + AMO_LPBFifoSat= 0x0100FF04, + AMO_LPBIntFlag= 0x0100FF08, + AMO_LPBFmBufA0= 0x0100FF0C, + AMO_LPBFmBufA1= 0x0100FF10, + AMO_LPBRdWtAdr= 0x0100FF14, + AMO_LPBRdWtDat= 0x0100FF18, + AMO_LPBIOPort = 0x0100FF1C, + AMO_LPBSerPort= 0x0100FF20, + AMO_LPBVidInWinSz= 0x0100FF24, + AMO_LPBVidDatOffs= 0x0100FF28, + AMO_LPBHorScalCtrl= 0x0100FF2C, + AMO_LPBVerDeciCtrl= 0x0100FF30, + AMO_LPBLnStride= 0x0100FF34, + AMO_LPBFmBufAddr2= 0x0100FF38, + AMO_LPBVidCapVDCtrl=0x0100FF3C, + + AMO_LPBVidCapFdStAd=0x0100FF60, + AMO_LPBVidCapFdMdAd=0x0100FF64, + AMO_LPBVidCapFdBtAd=0x0100FF68, + AMO_LPBVidCapFdSize=0x0100FF6C, + AMO_LPBBilinDecim1= 0x0100FF70, + AMO_LPBBilinDecim2= 0x0100FF74, + AMO_LPBBilinDecim3= 0x0100FF78, + AMO_LPBDspVEUHorSRR=0x0100FF7C, + AMO_LPBDspVEUVerSRR=0x0100FF80, + AMO_LPBDspVeuDnScDR=0x0100FF84, + AMO_LPB_VEUERPReg= 0x0100FF88, + AMO_LPB_VBISelReg= 0x0100FF8C, + AMO_LPB_VBIBasAdReg=0x0100FF90, + AMO_LPB_DatOffsReg= 0x0100FF94, + AMO_LPB_VBIVerDcReg=0x0100FF98, + AMO_LPB_VBICtrlReg= 0x0100FF9C, + AMO_LPB_VIPXferCtrl=0x0100FFA0, + AMO_LPB_FIFOWtMark= 0x0100FFA4, + AMO_LPB_FIFOCount= 0x0100FFA8, + AMO_LPBFdSkipPat= 0x0100FFAC, + AMO_LPBCapVEUHorSRR=0x0100FFB0, + AMO_LPBCapVEUVerSRR=0x0100FFB4, + AMO_LPBCapVeuDnScDR=0x0100FFB8 + +}AddressMapOffset; +/*more to add*/ + + +typedef enum { + CMD_DrawPrim=0x10, /*10000*/ + CMD_DrawIdxPrim=0x11, /*10001*/ + CMD_SetRegister=0x12, /*10010*/ + CMD_UpdateShadowStat=0x13 , /*10011*/ + CMD_PageFlip=0x14, /* 10100*/ + CMD_BusMasterImgXfer=0x15, /* 10101*/ + CMD_ScaledImgXfer=0x16, /* 10110*/ + CMD_Macroblock=0x17, /*10111*/ + CMD_Wait= 0x18, /*11000*/ + CMD_2D_NOP=0x08, /* 01000*/ + CMD_2D_RCT=0x09, /*01001 rectangular fill*/ + CMD_2D_SCNL=0x0a, /* 01010 scan line*/ + CMD_2D_LIN=0x0b, /*01011 line*/ + CMD_2D_SMTXT=0x0c, /*01100*/ + CMD_2D_BPTXT=0x0d, /*01101*/ + CMD_InitFlag=0x1f /*11111, for S/W initialization control*/ +}Command; + + +typedef enum { + VRR_List, + VRR_Strip, + VRR_Fan, + VRR_QuadList +}VertexReplaceRule; + +/*********************** + Destination +************************/ + +typedef enum { + DFT_RGB565 = 0, + DFT_XRGB8888 +}DestinationFmt; + + +/************************* + Z Buffer / Alpha test +*************************/ + +typedef enum { + ZCF_Never, + ZCF_Less, + ZCF_Equal, + ZCF_LessEqual, + ZCF_Greater, + ZCF_NotEqual, + ZCF_GreaterEqual, + ZCF_Always +}ZCmpFunc; /* same for Alpha test compare function*/ + + +typedef enum { + ZDS_16i, /* .16 fixed*/ + ZDS_32f /* 1.8.15 float*/ +}ZDepthSelect; + + +/********************************** + BCI Register Addressing Index +***********************************/ +typedef enum { + + CRI_VTX0_X = 0x00, + CRI_VTX0_Y = 0x01, + CRI_VTX0_W = 0x02, + CRI_VTX0_DIFFU= 0x03, + CRI_VTX0_SPECU= 0x04, + CRI_VTX0_U = 0x05, + CRI_VTX0_V = 0x06, + CRI_VTX0_U2 = 0x07, + CRI_VTX0_V2 = 0x08, + CRI_VTX1_X = 0x09, + CRI_VTX1_Y = 0x0a, + CRI_VTX1_W = 0x0b, + CRI_VTX1_DIFFU= 0x0c, + CRI_VTX1_SPECU= 0x0d, + CRI_VTX1_U = 0x0e, + CRI_VTX1_V = 0x0f, + CRI_VTX1_U2 = 0x10, + CRI_VTX1_V2 = 0x11, + CRI_VTX2_X = 0x12, + CRI_VTX2_Y = 0x13, + CRI_VTX2_W = 0x14, + CRI_VTX2_DIFFU= 0x15, + CRI_VTX2_SPECU= 0x16, + CRI_VTX2_U = 0x17, + CRI_VTX2_V = 0x18, + CRI_VTX2_U2 = 0x19, + CRI_VTX2_V2 = 0x1a, + + CRI_ZPixelOffset = 0x1d, + CRI_DrawCtrlLocal = 0x1e, + CRI_TexPalAddr = 0x1f, + CRI_TexCtrl0 = 0x20, + CRI_TexCtrl1 = 0x21, + CRI_TexAddr0 = 0x22, + CRI_TexAddr1 = 0x23, + CRI_TexBlendCtrl0 = 0x24, + CRI_TexBlendCtrl1 = 0x25, + CRI_TexXprClr = 0x26, + CRI_TexDescr = 0x27, + + CRI_FogTable00= 0x28, + CRI_FogTable04= 0x29, + CRI_FogTable08= 0x2a, + CRI_FogTable12= 0x2b, + CRI_FogTable16= 0x2c, + CRI_FogTable20= 0x2d, + CRI_FogTable24= 0x2e, + CRI_FogTable28= 0x2f, + CRI_FogCtrl= 0x30, + CRI_StencilCtrl= 0x31, + CRI_ZBufCtrl= 0x32, + CRI_ZBufOffset= 0x33, + CRI_DstCtrl= 0x34, + CRI_DrawCtrlGlobal0= 0x35, + CRI_DrawCtrlGlobal1= 0x36, + CRI_ZRW_WTMK = 0x37, + CRI_DST_WTMK = 0x38, + CRI_TexBlendColor= 0x39, + + CRI_VertBufAddr= 0x3e, + /* new in ms1*/ + CRI_MauFrameAddr0 = 0x40, + CRI_MauFrameAddr1 = 0x41, + CRI_MauFrameAddr2 = 0x42, + CRI_MauFrameAddr3 = 0x43, + CRI_FrameDesc = 0x44, + CRI_IDCT9bitEn = 0x45, + CRI_MV0 = 0x46, + CRI_MV1 = 0x47, + CRI_MV2 = 0x48, + CRI_MV3 = 0x49, + CRI_MacroDescr = 0x4a, /*kickoff?*/ + + CRI_MeuCtrl = 0x50, + CRI_SrcYAddr = 0x51, + CRI_DestAddr = 0x52, + CRI_FmtrSrcDimen = 0x53, + CRI_FmtrDestDimen = 0x54, + CRI_SrcCbAddr = 0x55, + CRI_SrcCrAddr = 0x56, + CRI_SrcCrCbStride = 0x57, + + CRI_BCI_Power= 0x5f, + + CRI_PSCtrl=0xA0, + CRI_SSClrKeyCtrl=0xA1, + CRI_SSCtrl=0xA4, + CRI_SSChromUpBound=0xA5, + CRI_SSHoriScaleCtrl=0xA6, + CRI_SSClrAdj=0xA7, + CRI_SSBlendCtrl=0xA8, + CRI_PSFBAddr0=0xB0, + CRI_PSFBAddr1=0xB1, + CRI_PSStride=0xB2, + CRI_DB_LPB_Support=0xB3, + CRI_SSFBAddr0=0xB4, + CRI_SSFBAddr1=0xB5, + CRI_SSStride=0xB6, + CRI_SSOpaqueCtrl=0xB7, + CRI_SSVertScaleCtrl=0xB8, + CRI_SSVertInitValue=0xB9, + CRI_SSSrcLineCnt=0xBA, + CRI_FIFO_RAS_Ctrl=0xBB, + CRI_PSWinStartCoord=0xBC, + CRI_PSWinSize=0xBD, + CRI_SSWinStartCoord=0xBE, + CRI_SSWinSize=0xBF, + CRI_PSFIFOMon0=0xC0, + CRI_SSFIFOMon0=0xC1, + CRI_PSFIFOMon1=0xC2, + CRI_SSFIFOMon1=0xC3, + CRI_PSFBSize=0xC4, + CRI_SSFBSize=0xC5, + CRI_SSFBAddr2=0xC6, + /* 2D register starts at D0*/ + CRI_CurrXY=0xD0, + CRI_DstXYorStep=0xD1 , + CRI_LineErr=0xD2 , + CRI_DrawCmd=0xD3, /*kick off for image xfer*/ + CRI_ShortStrkVecXfer=0xD4, + CRI_BackClr=0xD5, + CRI_ForeClr=0xD6, + CRI_BitPlaneWtMask=0xD7, + CRI_BitPlaneRdMask=0xD8, + CRI_ClrCmp=0xD9 , + CRI_BackAndForeMix=0xDA , + CRI_TopLeftSciss=0xDB , + CRI_BotRightSciss=0xDC , + CRI_PixOrMultiCtrl=0xDD , + CRI_MultiCtrlOrRdSelct=0xDE , + CRI_MinorOrMajorAxisCnt=0xDF , + CRI_GlobalBmpDesc1=0xE0 , + CRI_GlobalBmpDesc2=0xE1 , + CRI_BurstPriBmpDesc1=0xE2 , + CRI_BurstPriBmpDesc2=0xE3 , + CRI_BurstSecBmpDesc1=0xE4 , + CRI_BurstSecBmpDesc2=0xE5, + CRI_ImageDataPort=0xF8 + +}CtrlRegIdx; + +/*********************** + Fog Mode +************************/ +typedef enum +{ + FGM_Z_FOG, /*Table*/ + FGM_V_FOG /*Vertex*/ +} FogMode; + +/*********************** + Texture +************************/ +typedef enum +{ + TAM_Wrap, + TAM_Clamp, + TAM_Mirror +} TexAddressModel; + +typedef enum +{ + TFT_S3TC4Bit, + TFT_Pal8Bit565, + TFT_Pal8Bit1555, + TFT_ARGB8888, + TFT_ARGB1555, + TFT_ARGB4444, + TFT_RGB565, + TFT_Pal8Bit4444, + TFT_S3TC4A4Bit, /*like S3TC4Bit but with 4 bit alpha*/ + TFT_S3TC4CA4Bit, /*like S3TC4Bit, but with 4 bit compressed alpha*/ + TFT_S3TCL4, + TFT_S3TCA4L4, + TFT_L8, + TFT_A4L4, + TFT_I8, + TFT_A8 +} TexFmt; + +typedef enum +{ + TPS_64, + TPS_128, + TPS_192, + TPS_256 +} TexPaletteSize; + + #define MAX_MIPMAP_LOD_BIAS 255 + #define MIN_MIPMAP_LOD_BIAS -255 + +typedef enum +{ + TFM_Point, /*1 TPP*/ + TFM_Bilin, /*2 TPP*/ + TFM_Reserved, + TFM_Trilin /*16 TPP*/ +} TexFilterMode; + + +#define TBC_Decal 0x00850410 +#define TBC_Modul 0x00850011 +#define TBC_DecalAlpha 0x00852A04 +#define TBC_ModulAlpha 0x00110011 +#define TBC_Copy 0x00840410 +#define TBC_CopyAlpha 0x00900405 +#define TBC_NoTexMap 0x00850405 +#define TBC_Blend0 0x00810004 +#define TBC_Blend1 0x00870e02 +#define TBC_BlendAlpha0 0x00040004 +#define TBC_BlendAlpha1 TBC_Blend1 +#define TBC_BlendInt0 0x00040004 +#define TBC_BlendInt1 0x01c20e02 +#define TBC_AddAlpha 0x19910c11 + +#define TBC_Decal1 0x00870410 +#define TBC_Modul1 0x00870013 +#define TBC_DecalAlpha1 0x00832A00 +#define TBC_ModulAlpha1 0x00130013 +#define TBC_NoTexMap1 0x00870407 +#define TBC_Copy1 0x00870400 +#define TBC_CopyAlpha1 0x00900400 +#define TBC_AddAlpha1 0x19930c13 + +/* + * derived from TexBlendCtrl + */ + +typedef enum +{ + TBC_UseSrc, + TBC_UseTex, + TBC_TexTimesSrc, + TBC_BlendTexWithSrc +} TexBlendCtrlMode; + +/*********************** + Draw Control +************************/ +typedef enum +{ + BCM_Reserved, + BCM_None, + BCM_CW, + BCM_CCW +} BackfaceCullingMode; + +typedef enum +{ + SAM_Zero, + SAM_One, + SAM_DstClr, + SAM_1DstClr, + SAM_SrcAlpha, + SAM_1SrcAlpha, + SAM_DstAlpha, + SAM_1DstAlpha +} SrcAlphaBlendMode; + +/* -1 from state*/ +typedef enum +{ + DAM_Zero, + DAM_One, + DAM_SrcClr, + DAM_1SrcClr, + DAM_SrcAlpha, + DAM_1SrcAlpha, + DAM_DstAlpha, + DAM_1DstAlpha +} DstAlphaBlendMode; + +/* + * stencil control + */ + +typedef enum +{ + STC_COMP_Never, + STC_COMP_Less, + STC_COMP_Equal, + STC_COMP_LessEqual, + STC_COMP_Greater, + STC_COMP_NotEqual, + STC_COMP_GreaterEqual, + STC_COMP_Always +} StencilCompareMode; + +typedef enum +{ + STC_FAIL_Keep, + STC_FAIL_Zero, + STC_FAIL_Equal, + STC_FAIL_IncClamp, + STC_FAIL_DecClamp, + STC_FAIL_Invert, + STC_FAIL_Inc, + STC_FAIL_Dec +} StencilFailOp; + +typedef enum +{ + STC_ZPASS_Keep, + STC_ZPASS_Zero, + STC_ZPASS_Equal, + STC_ZPASS_IncClamp, + STC_ZPASS_DecClamp, + STC_ZPASS_Invert, + STC_ZPASS_Inc, + STC_ZPASS_Dec +} StencilZPassOp; + +typedef enum +{ + STC_ZFAIL_Keep, + STC_ZFAIL_Zero, + STC_ZFAIL_Equal, + STC_ZFAIL_IncClamp, + STC_ZFAIL_DecClamp, + STC_ZFAIL_Invert, + STC_ZFAIL_Inc, + STC_ZFAIL_Dec +} StencilZFailOp; + +/*************************************************************** +*** Bitfield Structures for Programming Interface ************** +***************************************************************/ + +/************************** + Command Header Entry +**************************/ + +typedef struct { /*for DrawIndexPrimitive command, vert0Idx is meaningful.*/ + unsigned int vert0Idx:16; + unsigned int vertCnt:8; + unsigned int cont:1; + unsigned int type:2; /*00=list, 01=strip, 10=fan, 11=reserved*/ + unsigned int cmd:5; +}Reg_DrawIndexPrimitive; + +typedef struct { /*for DrawIndexPrimitive command, vert0Idx is meaningful.*/ + unsigned int noW:1; + unsigned int noCd:1; + unsigned int noCs:1; + unsigned int noU:1; + unsigned int noV:1; + unsigned int noU2:1; + unsigned int noV2:1; + + unsigned int reserved:9; + unsigned int vertCnt:8; + unsigned int cont:1; + unsigned int type:2; /* 00=list, 01=strip, 10=fan, 11=reserved*/ + unsigned int cmd:5; +}Reg_DrawPrimitive; + + +typedef struct { + unsigned int startRegIdx:8; + unsigned int reserved:8; + unsigned int regCnt:8; + unsigned int resvered1:1; + unsigned int lowEn:1; + unsigned int highEn:1; + unsigned int cmd:5; +}Reg_SetRegister; + +typedef struct { + unsigned int reserved1:22; + unsigned int isPrimary:1; + unsigned int MIU_SYNC:1; + unsigned int reserved2:3; + unsigned int cmd:5; +}Reg_QueuedPageFlip; + +typedef struct { + unsigned int reserved1:22; + unsigned int DIR:1; + unsigned int CTG:1; /*set to 0*/ + unsigned int BPP:1; + unsigned int reserved2:1; + unsigned int cmd:5; +}Reg_MasterImgXfer; + +typedef struct { + unsigned int PD:4; /*PM=mono, PS=descriptor specified*/ + unsigned int PT:1; + unsigned int SD:4; + unsigned int ST:1; + unsigned int DD:3; + unsigned int DC:2; /*DC=destination clip*/ + unsigned int CS:1; /*cs=color specified*/ + unsigned int MIX3:8; + unsigned int XP:1; + unsigned int YP:1; + unsigned int LP:1; + unsigned int cmd:5; +}Reg_2D; + +typedef struct { + unsigned int CodedBlkPattern:6; + unsigned int DCT_Type:1; + unsigned int MB_Type:2; + unsigned int MotionType:2; + unsigned int MB_Row:6; + unsigned int MB_Column:6; + unsigned int mv3:1; + unsigned int mv2:1; + unsigned int mv1:1; + unsigned int mv0:1; + unsigned int cmd:5; +}Reg_MacroBlock; + +typedef struct { + unsigned int scanLnCnt:11; + unsigned int clkCnt:5; + unsigned int e3d:1; + unsigned int e2d:1; + unsigned int mau:1; + unsigned int veu:1; + unsigned int meuMit:1; + unsigned int meuSit:1; + unsigned int meuVx:1; + unsigned int meuMau:1; + unsigned int pageFlip:1; + unsigned int scanLn:1; + unsigned int clk:1; + unsigned int cmd:5; +}Reg_Wait; + +typedef struct{ + unsigned int reserved:27; + unsigned int cmd:5; +}Reg_ScaledImgXfer ; + +typedef struct{ + unsigned int eventTag:16; + unsigned int reserved2:6; + unsigned int ET:1; + unsigned int INT:1; + unsigned int reserved1:3; + unsigned int cmd:5; +}Reg_UpdtShadowStat; + +typedef union { + Reg_DrawPrimitive vert; + Reg_DrawIndexPrimitive vertIdx; + Reg_SetRegister set; + Reg_QueuedPageFlip pageFlip; + Reg_MasterImgXfer masterImgXfer; + Reg_ScaledImgXfer scaledImgXfer; + Reg_UpdtShadowStat updtShadow; + Reg_MacroBlock macroBlk; + Reg_2D cmd2D; + Reg_Wait wait; +}CmdHeaderUnion; + + +/*frank 2001/11/14 add BCI write macros*/ +/* Registers not used in the X server + */ + +#define SAVAGE_NOP_ID 0x2094 +#define SAVAGE_NOP_ID_MASK ((1<<22)-1) + + +/* 3D instructions + */ + +/* Draw Primitive Control */ + + +#define SAVAGE_HW_NO_Z (1<<0) +#define SAVAGE_HW_NO_W (1<<1) +#define SAVAGE_HW_NO_CD (1<<2) +#define SAVAGE_HW_NO_CS (1<<3) +#define SAVAGE_HW_NO_UV0 ((1<<4) | (1<<5)) +#define SAVAGE_HW_NO_UV1 ((1<<6) | (1<<7)) + +#define SAVAGE_HW_TRIANGLE_TYPE (3UL<<25) +#define SAVAGE_HW_TRIANGLE_CONT (1UL<<24) +#define SAVAGE_HW_TRIANGLE_LIST (0<<25) +#define SAVAGE_HW_TRIANGLE_STRIP (1<<25) +#define SAVAGE_HW_TRIANGLE_FAN (2<<25) +#define SAVAGE_HW_QUAD (3<<25) + +#define __HW_TEXTURE_CHANGED 0x00002FE +#define __HW_HAS_SCISSORS_CHANGED 0x00001800 +#define __HW_ALL_CHANGED 0x1FFFFFF +/*Frank 2001/11/14 Wait commands*/ +#define WAIT_3D_IDLE 0xC0010000 +#define WAIT_3D_2D_IDLE 0xC0030000 + +#define SET_REGISTER(index, count) \ + ((CMD_SetRegister << 27) | (0x6000000) | ((count) << 16) | (index)) + +/*frank 2001/11/20 */ +#define MAXLOOP 0xFFFFFF +/*#define MAXFIFO 0x7F00*/ +#define MAXFIFO 0x1FF00 + +/* get eventtag from shadow status */ +/* here we use eventTag1 because eventTag0 is used by HWXvMC*/ +#define GET_EVENTTAG \ + (((*(volatile GLuint *)(imesa->MMIO_BASE+0x48c04)) & 0xffff0000L)>>16) + +#define SHADOW_WAIT(imesa ) do \ +{ \ + int loop=0; \ + imesa->shadowCounter = (imesa->shadowCounter + 1) & 0xffff;\ + if(imesa->shadowCounter == 0)\ + imesa->shadowCounter = MAX_SHADOWCOUNTER;\ + *(volatile GLuint *)imesa->BCIBase = imesa->shadowCounter | 0x98400000L;\ + while(\ + (GET_EVENTTAG) != imesa->shadowCounter &&\ + (loop++ < MAXLOOP));\ +}while(0); + +#define SHADOW_WAIT_IDLE(imesa ) do \ +{ \ + int loop=0; \ + imesa->shadowCounter = (imesa->shadowCounter + 1) & 0xffff;\ + if(imesa->shadowCounter == 0)\ + imesa->shadowCounter = MAX_SHADOWCOUNTER;\ +/* *(volatile GLuint *)imesa->BCIBase = WAIT_3D_IDLE;\*/\ + *(volatile GLuint *)imesa->BCIBase = imesa->shadowCounter | 0x98400000L;\ + while ( \ + (GET_EVENTTAG) != imesa->shadowCounter && \ + (loop++ < MAXLOOP)); \ +}while(0); + +#if 0 +#define ALT_STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c60)) + +#define PAGE_PENDING(result) do{\ +result=((ALT_STATUS_WORD0 & 0x08000000)?GL_TRUE:GL_FALSE);\ +}while(0) + +#define WAIT_FOR_FIFO(count) do{\ +int loop = 0; \ +int slots = MAXFIFO-count; \ +while(((ALT_STATUS_WORD0 &0x001fffff)>slots)&&(loop++<MAXLOOP)); \ +}while(0) + + +#define WAIT_IDLE_EMPTY do{\ +int loop = 0; \ + if (/*imesa->shadowStatus*/0)\ + {\ + SHADOW_WAIT_IDLE(imesa);\ + }\ + else\ + { \ + while(((ALT_STATUS_WORD0 &0x00ffffff)!=0x00E00000L)&&(loop++<MAXLOOP));\ + }\ +}while(0) + +#define WAIT_IDLE do{\ +int loop = 0; \ +if (imesa->shadowStatus)\ + while((((*imesa->shadowPointer) & 0x0E000000L)!=0x0E000000L)&&(loop++<MAXLOOP));\ +else\ +while(((ALT_STATUS_WORD0 &0x00E00000)!=0x00E00000L)&&(loop++<MAXLOOP)); \ +}while(0) +#endif /* 0 */ + +#define SAVAGE_DRAW_PRIMITIVE(count, typeandvertexSkip, isCont) \ + ( ((count)<<16) | (typeandvertexSkip) | (isCont | (1<<31))); + +static __inline volatile GLuint * SAVAGE_GET_BCI_POINTER(savageContextPtr imesa, GLuint count) +{ + WAIT_FOR_FIFO(count); + return (volatile GLuint *)(imesa->BCIBase); +} + +/*use this set bci cmd now!*/ +#define WRITE_CMD(buf,cmd,type) do {\ + *((type*)buf)=cmd;\ + buf++;\ + }while(0) +#endif + + + + + + diff --git a/src/mesa/drivers/dri/savage/savage_init.h b/src/mesa/drivers/dri/savage/savage_init.h new file mode 100644 index 0000000000..c55c62df9c --- /dev/null +++ b/src/mesa/drivers/dri/savage/savage_init.h @@ -0,0 +1,161 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#ifndef _SAVAGE_INIT_H_ +#define _SAVAGE_INIT_H_ + +#ifdef GLX_DIRECT_RENDERING + +#include <sys/time.h> +#include "dri_util.h" +#include "mtypes.h" + +typedef struct { + drmHandle handle; + drmSize size; + char *map; +} savageRegion, *savageRegionPtr; + +typedef struct { + savageRegion front; + savageRegion back; + savageRegion depth; + savageRegion aperture; + + int chipset; + int width; + int height; + int mem; + + int cpp; /* for front and back buffers */ + int zpp; +#if 0 + int bitsPerPixel; +#endif + unsigned int frontFormat; + unsigned int frontOffset; + unsigned int frontPitch; + unsigned int frontBitmapDesc; + + unsigned int backOffset; + unsigned int backBitmapDesc; + unsigned int depthOffset; + unsigned int depthBitmapDesc; + + unsigned int backPitch; + unsigned int backPitchBits; + + unsigned int textureOffset[SAVAGE_NR_TEX_HEAPS]; + unsigned int textureSize[SAVAGE_NR_TEX_HEAPS]; + unsigned int logTextureGranularity[SAVAGE_NR_TEX_HEAPS]; + drmAddress texVirtual[SAVAGE_NR_TEX_HEAPS]; + + __DRIscreenPrivate *driScrnPriv; + drmBufMapPtr bufs; + int use_copy_buf; + unsigned int sarea_priv_offset; +} savageScreenPrivate; + + +#include "savagecontext.h" + +extern void savageGetLock( savageContextPtr imesa, GLuint flags ); +extern void savageEmitHwStateLocked( savageContextPtr imesa ); +extern void savageEmitScissorValues( savageContextPtr imesa, int box_nr, int emit ); +extern void savageEmitDrawingRectangle( savageContextPtr imesa ); +extern void savageXMesaSetBackClipRects( savageContextPtr imesa ); +extern void savageXMesaSetFrontClipRects( savageContextPtr imesa ); + + +#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) \ + savageGetLock( imesa, 0 ); \ + } while (0) + + + +/* Unlock the hardware using the global current context + */ +#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 ); \ + savageRegetLockQuiescent( imesa ); \ +} while(0) + +/* The following definitions are copied from savage_regs.h in the XFree86 + * driver. They are unlikely to change. If they do we need to keep them in + * sync. */ + +#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) + +#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \ + || (chip==S3_PROSAVAGE) \ + || (chip==S3_TWISTER) \ + || (chip==S3_PROSAVAGEDDR)) + +#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE)) + +#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000)) + +#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) \ + ||(chip==S3_PROSAVAGEDDR)) + +/* Chip tags. These are used to group the adapters into + * related families. + */ + +enum S3CHIPTAGS { + S3_UNKNOWN = 0, + S3_SAVAGE3D, + S3_SAVAGE_MX, + S3_SAVAGE4, + S3_PROSAVAGE, + S3_TWISTER, + S3_PROSAVAGEDDR, + S3_SUPERSAVAGE, + S3_SAVAGE2000, + S3_LAST +}; + +#endif +#endif diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c new file mode 100644 index 0000000000..bc15e0bd30 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -0,0 +1,800 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#ifdef GLX_DIRECT_RENDERING + +#include <X11/Xlibint.h> +#include <stdio.h> + +#include "savagecontext.h" +#include "context.h" +#include "matrix.h" + +#include "simple_list.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "array_cache/acache.h" + +#include "tnl/t_pipeline.h" + +#include "drivers/common/driverfuncs.h" + +#include "savagedd.h" +#include "savagestate.h" +#include "savagetex.h" +#include "savagespan.h" +#include "savagetris.h" +#include "savagevb.h" +#include "savageioctl.h" +#include "savage_bci.h" + +#include "savage_dri.h" + +#include "savagedma.h" + +#ifndef SAVAGE_DEBUG +int SAVAGE_DEBUG = (0 +/* | DEBUG_ALWAYS_SYNC */ +/* | DEBUG_VERBOSE_RING */ +/* | DEBUG_VERBOSE_OUTREG */ +/* | DEBUG_VERBOSE_MSG */ +/* | DEBUG_NO_OUTRING */ +/* | DEBUG_NO_OUTREG */ +/* | DEBUG_VERBOSE_API */ +/* | DEBUG_VERBOSE_2D */ +/* | DEBUG_VERBOSE_DRI */ +/* | DEBUG_VALIDATE_RING */ +/* | DEBUG_VERBOSE_IOCTL */ + ); +#endif + + +/*For time caculating test*/ +#if defined(DEBUG_TIME) && DEBUG_TIME +struct timeval tv_s,tv_f; +unsigned long time_sum=0; +struct timeval tv_s1,tv_f1; +#endif + +/* this is first function called in dirver*/ + +static GLboolean +savageInitDriver(__DRIscreenPrivate *sPriv) +{ + savageScreenPrivate *savageScreen; + SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv; + + + /* Check the DRI version */ + { + int major, minor, patch; + if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { + if (major != 4 || minor < 0) { + __driUtilMessage("savage DRI driver expected DRI version 4.0.x but got version %d.%d.%d", major, minor, patch); + return GL_FALSE; + } + } + } + + /* Check that the DDX driver version is compatible */ + if (sPriv->ddxMajor != 1 || + sPriv->ddxMinor < 0) { + __driUtilMessage("savage 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 < 0) { + __driUtilMessage("savage DRI driver expected DRM driver version 1.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + return GL_FALSE; + } + + /* Allocate the private area */ + savageScreen = (savageScreenPrivate *)Xmalloc(sizeof(savageScreenPrivate)); + if (!savageScreen) + return GL_FALSE; + + savageScreen->driScrnPriv = sPriv; + sPriv->private = (void *)savageScreen; + + savageScreen->chipset=gDRIPriv->chipset; + savageScreen->width=gDRIPriv->width; + savageScreen->height=gDRIPriv->height; + savageScreen->mem=gDRIPriv->mem; + savageScreen->cpp=gDRIPriv->cpp; + savageScreen->zpp=gDRIPriv->zpp; + savageScreen->frontPitch=gDRIPriv->frontPitch; + savageScreen->frontOffset=gDRIPriv->frontOffset; + savageScreen->frontBitmapDesc = gDRIPriv->frontBitmapDesc; + + if (gDRIPriv->cpp == 4) + savageScreen->frontFormat = DV_PF_8888; + else + savageScreen->frontFormat = DV_PF_565; + + savageScreen->backOffset = gDRIPriv->backOffset; + savageScreen->backBitmapDesc = gDRIPriv->backBitmapDesc; + savageScreen->depthOffset=gDRIPriv->depthOffset; + savageScreen->depthBitmapDesc = gDRIPriv->depthBitmapDesc; +#if 0 + savageScreen->backPitch = gDRIPriv->auxPitch; + savageScreen->backPitchBits = gDRIPriv->auxPitchBits; +#endif + savageScreen->textureOffset[SAVAGE_CARD_HEAP] = + gDRIPriv->textureOffset; + savageScreen->textureSize[SAVAGE_CARD_HEAP] = + gDRIPriv->textureSize; + savageScreen->logTextureGranularity[SAVAGE_CARD_HEAP] = + gDRIPriv->logTextureGranularity; + + savageScreen->textureOffset[SAVAGE_AGP_HEAP] = + gDRIPriv->agpTextures.handle; + savageScreen->textureSize[SAVAGE_AGP_HEAP] = + gDRIPriv->agpTextures.size; + savageScreen->logTextureGranularity[SAVAGE_AGP_HEAP] = + gDRIPriv->logAgpTextureGranularity; + + savageScreen->back.handle = gDRIPriv->backbuffer; + savageScreen->back.size = gDRIPriv->backbufferSize; + savageScreen->back.map = + (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->backOffset); + + savageScreen->depth.handle = gDRIPriv->depthbuffer; + savageScreen->depth.size = gDRIPriv->depthbufferSize; + + savageScreen->depth.map = + (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->depthOffset); + + savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset; + + savageScreen->texVirtual[SAVAGE_CARD_HEAP] = + (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->textureOffset); +#if 0 + savageDDFastPathInit(); + savageDDTrifuncInit(); + savageDDSetupInit(); +#endif + return GL_TRUE; +} + +/* Accessed by dlsym from dri_mesa_init.c + */ +static void +savageDestroyScreen(__DRIscreenPrivate *sPriv) +{ + savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private; + + + Xfree(savageScreen); + sPriv->private = NULL; +} + +#if 0 +GLvisual *XMesaCreateVisual(Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config) +{ + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. + */ + return _mesa_create_visual( config->rgba, + config->doubleBuffer, + config->stereo, + _mesa_bitcount(visinfo->red_mask), + _mesa_bitcount(visinfo->green_mask), + _mesa_bitcount(visinfo->blue_mask), + config->alphaSize, + 0, /* index bits */ + config->depthSize, + config->stencilSize, + config->accumRedSize, + config->accumGreenSize, + config->accumBlueSize, + config->accumAlphaSize, + 0 /* num samples */ ); +} +#endif + + +static GLboolean +savageCreateContext( const __GLcontextModes *mesaVis, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ) +{ + GLcontext *ctx, *shareCtx; + savageContextPtr imesa; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + struct dd_function_table functions; + SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv; + savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private; + drm_savage_sarea_t *saPriv=(drm_savage_sarea_t *)(((char*)sPriv->pSAREA)+ + savageScreen->sarea_priv_offset); + int i; + imesa = (savageContextPtr)Xcalloc(sizeof(savageContext), 1); + if (!imesa) { + return GL_FALSE; + } + + /* Init default driver functions then plug in savage-specific texture + * functions that are needed as early as during context creation. */ + _mesa_init_driver_functions( &functions ); + savageDDInitTextureFuncs( &functions ); + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((savageContextPtr) sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + ctx = _mesa_create_context(mesaVis, shareCtx, &functions, imesa); + if (!ctx) { + Xfree(imesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = imesa; + + /* BEGIN;*/ + /* 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. + */ + if (savageScreen->textureSize[SAVAGE_CARD_HEAP] < 2*1024*1024) { + ctx->Const.MaxTextureLevels = 9; + } else if (savageScreen->textureSize[SAVAGE_CARD_HEAP] < 8*1024*1024) { + ctx->Const.MaxTextureLevels = 10; + } else { + ctx->Const.MaxTextureLevels = 11; + } + if (savageScreen->chipset >= S3_SAVAGE4) + ctx->Const.MaxTextureUnits = 2; + else + ctx->Const.MaxTextureUnits = 1; + +#if 0 + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = 3.0; + ctx->Const.MaxLineWidthAA = 3.0; + ctx->Const.LineWidthGranularity = 1.0; +#endif + + /* Dri stuff + */ + imesa->hHWContext = driContextPriv->hHWContext; + imesa->driFd = sPriv->fd; + imesa->driHwLock = &sPriv->pSAREA->lock; + + imesa->savageScreen = savageScreen; + imesa->driScreen = sPriv; + imesa->sarea = saPriv; + imesa->glBuffer = NULL; + + /* DMA buffer */ + + /*The shadow pointer*/ + imesa->shadowPointer = + (volatile GLuint *)((((GLuint)(&saPriv->shadow_status)) + 31) & 0xffffffe0L) ; + /* here we use eventTag1 because eventTag0 is used by HWXvMC*/ + imesa->eventTag1 = (volatile GLuint *)(imesa->shadowPointer + 6); + /* imesa->eventTag1=(volatile GLuint *)(imesa->MMIO_BASE+0x48c04);*/ + imesa->shadowCounter = MAX_SHADOWCOUNTER; + imesa->shadowStatus = GL_TRUE;/*Will judge by 2d message */ + + if (drmMap(sPriv->fd, + gDRIPriv->registers.handle, + gDRIPriv->registers.size, + (drmAddress *)&(gDRIPriv->registers.map)) != 0) + { + Xfree(savageScreen); + sPriv->private = NULL; + return GL_FALSE; + } + + if (drmMap(sPriv->fd, + gDRIPriv->agpTextures.handle, + gDRIPriv->agpTextures.size, + (drmAddress *)&(gDRIPriv->agpTextures.map)) != 0) + { + Xfree(savageScreen); + sPriv->private = NULL; + return GL_FALSE; + } + +/* agp texture*/ + savageScreen->texVirtual[SAVAGE_AGP_HEAP] = + (drmAddress)(gDRIPriv->agpTextures.map); + + + + gDRIPriv->BCIcmdBuf.map = (drmAddress *) + ((unsigned int)gDRIPriv->registers.map+0x00010000); + + imesa->MMIO_BASE = (GLuint)gDRIPriv->registers.map; + imesa->BCIBase= (GLuint)gDRIPriv->BCIcmdBuf.map; + + savageScreen->aperture.handle = gDRIPriv->aperture.handle; + savageScreen->aperture.size = gDRIPriv->aperture.size; + if (drmMap(sPriv->fd, + savageScreen->aperture.handle, + savageScreen->aperture.size, + (drmAddress *)&savageScreen->aperture.map) != 0) + { + Xfree(savageScreen); + sPriv->private = NULL; + return GL_FALSE; + } + + + + + + for(i=0;i<5;i++) + { + imesa->apertureBase[i] = ((GLuint)savageScreen->aperture.map + + 0x01000000 * i ); + + + } + + { + volatile unsigned int * tmp; + + tmp=(volatile unsigned int *)(imesa->MMIO_BASE + 0x850C); + + + tmp=(volatile unsigned int *)(imesa->MMIO_BASE + 0x48C40); + + + tmp=(volatile unsigned int *)(imesa->MMIO_BASE + 0x48C44); + + + tmp=(volatile unsigned int *)(imesa->MMIO_BASE + 0x48C48); + + + + } + + imesa->aperturePitch = gDRIPriv->aperturePitch; + + + /* change texHeap initialize to support two kind of texture heap*/ + /* here is some parts of initialization, others in InitDriver() */ + + imesa->lastTexHeap = savageScreen->texVirtual[SAVAGE_AGP_HEAP] ? 2 : 1; + + /*allocate texHeap for multi-tex*/ + { + int i; + + for(i=0;i<SAVAGE_NR_TEX_HEAPS;i++) + { + imesa->texHeap[i] = mmInit( 0, savageScreen->textureSize[i] ); + make_empty_list(&imesa->TexObjList[i]); + } + + make_empty_list(&imesa->SwappedOut); + } + + imesa->hw_stencil = GL_FALSE; +#if HW_STENCIL + imesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24; +#endif + imesa->depth_scale = (imesa->savageScreen->zpp == 2) ? + (1.0F/0x10000):(1.0F/0x1000000); + + /* Utah stuff + */ + imesa->new_state = ~0; + imesa->RenderIndex = ~0; + imesa->dirty = ~0; + imesa->vertex_format = 0; + imesa->TextureMode = ctx->Texture.Unit[0].EnvMode; + imesa->CurrentTexObj[0] = 0; + imesa->CurrentTexObj[1] = 0; + imesa->texAge[SAVAGE_CARD_HEAP]=0; + imesa->texAge[SAVAGE_AGP_HEAP]=0; + + /* Initialize the software rasterizer and helper modules. + */ + _swrast_CreateContext( ctx ); + _ac_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + + _swsetup_CreateContext( ctx ); + + /* Install the customized pipeline: + */ +#if 0 + _tnl_destroy_pipeline( ctx ); + _tnl_install_pipeline( ctx, savage_pipeline ); +#endif + + /* Configure swrast to match hardware characteristics: + */ + _swrast_allow_pixel_fog( ctx, GL_FALSE ); + _swrast_allow_vertex_fog( ctx, GL_TRUE ); + + ctx->DriverCtx = (void *) imesa; + imesa->glCtx = ctx; + if (savageDMAInit(imesa) == GL_FALSE) + return GL_FALSE; + + savageDDExtensionsInit( ctx ); + + savageDDInitStateFuncs( ctx ); + savageDDInitSpanFuncs( ctx ); + savageDDInitDriverFuncs( ctx ); + savageDDInitIoctlFuncs( ctx ); + savageInitTriFuncs( ctx ); + + savageInitVB( ctx ); + savageDDInitState( imesa ); + + driContextPriv->driverPrivate = (void *) imesa; + + return GL_TRUE; +} + +static void +savageDestroyContext(__DRIcontextPrivate *driContextPriv) +{ + savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate; + + assert (imesa); /* should never be NULL */ + if (imesa) { + savageTextureObjectPtr next_t, t; + + /* update for multi-tex*/ + { + int i; + for(i=0;i<SAVAGE_NR_TEX_HEAPS;i++) + foreach_s (t, next_t, &(imesa->TexObjList[i])) + savageDestroyTexObj(imesa, t); + } + foreach_s (t, next_t, &(imesa->SwappedOut)) + savageDestroyTexObj(imesa, t); + /*free the dma buffer*/ + savageDMAClose(imesa); + _swsetup_DestroyContext(imesa->glCtx ); + _tnl_DestroyContext( imesa->glCtx ); + _ac_DestroyContext( imesa->glCtx ); + _swrast_DestroyContext( imesa->glCtx ); + + savageFreeVB( imesa->glCtx ); + + /* free the Mesa context */ + imesa->glCtx->DriverCtx = NULL; + _mesa_destroy_context(imesa->glCtx); + + /* no longer use vertex_dma_buf*/ + Xfree(imesa); + } +} + +static GLboolean +savageCreateBuffer( __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { +#if HW_STENCIL + GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24; +#else + GLboolean swStencil = mesaVis->stencilBits > 0; +#endif + driDrawPriv->driverPrivate = (void *) + _mesa_create_framebuffer(mesaVis, + GL_FALSE, /* software depth buffer? */ + swStencil, + mesaVis->accumRedBits > 0, + mesaVis->alphaBits > 0 ); + + return (driDrawPriv->driverPrivate != NULL); + } +} + +static void +savageDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + +#if 0 +void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) +{ + /* XXX should do swap according to the buffer, not the context! */ + savageContextPtr imesa = savageCtx; + + FLUSH_VB( imesa->glCtx, "swap buffers" ); + savageSwapBuffers(imesa); +} +#endif + +void savageXMesaSetFrontClipRects( savageContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + + imesa->numClipRects = dPriv->numClipRects; + imesa->pClipRects = dPriv->pClipRects; + imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS; + imesa->drawX = dPriv->x; + imesa->drawY = dPriv->y; + + savageEmitDrawingRectangle( imesa ); +} + + +void savageXMesaSetBackClipRects( savageContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + + if (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; + } + + savageEmitDrawingRectangle( imesa ); + imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS; + + +} + + +static void savageXMesaWindowMoved( savageContextPtr imesa ) +{ + if (0) + fprintf(stderr, "savageXMesaWindowMoved\n\n"); + + switch (imesa->glCtx->Color._DrawDestMask) { + case FRONT_LEFT_BIT: + savageXMesaSetFrontClipRects( imesa ); + break; + case BACK_LEFT_BIT: + savageXMesaSetBackClipRects( imesa ); + break; + default: + break; + } +} + + +static GLboolean +savageUnbindContext(__DRIcontextPrivate *driContextPriv) +{ + savageContextPtr savage = (savageContextPtr) driContextPriv->driverPrivate; + if (savage) + savage->dirty = ~0; + + return GL_TRUE; +} + +static GLboolean +savageOpenFullScreen(__DRIcontextPrivate *driContextPriv) +{ + + + + if (driContextPriv) { + savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate; + imesa->IsFullScreen = GL_TRUE; + imesa->backup_frontOffset = imesa->savageScreen->frontOffset; + imesa->backup_backOffset = imesa->savageScreen->backOffset; + imesa->backup_frontBitmapDesc = imesa->savageScreen->frontBitmapDesc; + imesa->savageScreen->frontBitmapDesc = imesa->savageScreen->backBitmapDesc; + imesa->toggle = TARGET_BACK; + } + + return GL_TRUE; +} + +static GLboolean +savageCloseFullScreen(__DRIcontextPrivate *driContextPriv) +{ + + if (driContextPriv) { + savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate; + WAIT_IDLE_EMPTY; + imesa->IsFullScreen = GL_FALSE; + imesa->savageScreen->frontOffset = imesa->backup_frontOffset; + imesa->savageScreen->backOffset = imesa->backup_backOffset; + imesa->savageScreen->frontBitmapDesc = imesa->backup_frontBitmapDesc; + } + return GL_TRUE; +} + + +static GLboolean +savageMakeCurrent(__DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + if (driContextPriv) { + savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate; + + imesa->driReadable = driReadPriv; + imesa->driDrawable = driDrawPriv; + imesa->mesa_drawable = driDrawPriv; + imesa->dirty = ~0; + + _mesa_make_current2(imesa->glCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate); + + savageXMesaWindowMoved( imesa ); + + if (!imesa->glCtx->Viewport.Width) + _mesa_set_viewport(imesa->glCtx, 0, 0, + driDrawPriv->w, driDrawPriv->h); + } + else + { + _mesa_make_current(NULL, NULL); + } + return GL_TRUE; +} + + +void savageGetLock( savageContextPtr imesa, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + __DRIscreenPrivate *sPriv = imesa->driScreen; + drm_savage_sarea_t *sarea = imesa->sarea; + int me = imesa->hHWContext; + int stamp = dPriv->lastStamp; + int heap; + + + + /* We know there has been contention. + */ + drmGetLock(imesa->driFd, imesa->hHWContext, flags); + + + /* Note contention for throttling hint + */ + imesa->any_contend = 1; + + /* 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->dirty |= (SAVAGE_UPLOAD_CTX | + SAVAGE_UPLOAD_CLIPRECTS | + SAVAGE_UPLOAD_TEX0 | + SAVAGE_UPLOAD_TEX1); + imesa->Registers.changed.uiRegistersChanged = __HW_ALL_CHANGED; + 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. + */ + /*frank just for compiling,texAge,texList,AGP*/ + + for(heap= 0 ;heap < imesa->lastTexHeap ; heap++) + { + if (sarea->texAge[heap] != imesa->texAge[heap]) { + int sz = 1 << (imesa->savageScreen->logTextureGranularity[heap]); + int idx, nr = 0; + + /* Have to go right round from the back to ensure stuff ends up + * LRU in our local list... + */ + for (idx = sarea->texList[heap][SAVAGE_NR_TEX_REGIONS].prev ; + idx != SAVAGE_NR_TEX_REGIONS && nr < SAVAGE_NR_TEX_REGIONS ; + idx = sarea->texList[heap][idx].prev, nr++) + { + if (sarea->texList[heap][idx].age > imesa->texAge[heap]) + { + savageTexturesGone(imesa, heap ,idx * sz, sz, + sarea->texList[heap][idx].in_use); + } + } + + if (nr == SAVAGE_NR_TEX_REGIONS) + { + savageTexturesGone(imesa, heap, 0, + imesa->savageScreen->textureSize[heap], 0); + savageResetGlobalLRU( imesa , heap ); + } + + imesa->dirty |= SAVAGE_UPLOAD_TEX0IMAGE; + imesa->dirty |= SAVAGE_UPLOAD_TEX1IMAGE; + imesa->texAge[heap] = sarea->texAge[heap]; + } + } /* end of for loop */ + + if (dPriv->lastStamp != stamp) + savageXMesaWindowMoved( imesa ); + + + +} + + + +static const struct __DriverAPIRec savageAPI = { + savageInitDriver, + savageDestroyScreen, + savageCreateContext, + savageDestroyContext, + savageCreateBuffer, + savageDestroyBuffer, + savageSwapBuffers, + savageMakeCurrent, + savageUnbindContext, + savageOpenFullScreen, + savageCloseFullScreen +}; + + + +/* + * This is the bootstrap function for the driver. + * The __driCreateScreen name is the symbol that libGL.so fetches. + * Return: pointer to a __DRIscreenPrivate. + */ +void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, + int numConfigs, __GLXvisualConfig *config) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &savageAPI); + return (void *) psp; +} + + +#endif diff --git a/src/mesa/drivers/dri/savage/savagecontext.h b/src/mesa/drivers/dri/savage/savagecontext.h new file mode 100644 index 0000000000..6eaf58eca5 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagecontext.h @@ -0,0 +1,299 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + + +#ifndef SAVAGECONTEXT_INC +#define SAVAGECONTEXT_INC + +typedef struct savage_context_t savageContext; +typedef struct savage_context_t *savageContextPtr; +typedef struct savage_texture_object_t *savageTextureObjectPtr; + +#include <X11/Xlibint.h> +#include "dri_util.h" +#include "mtypes.h" +#include "xf86drm.h" +#include "drm.h" +#include "savage_drm.h" +#include "savage_sarea.h" +#include "savage_init.h" +#include "mm.h" + +#include "savagetex.h" +#include "savagedma.h" + +/* Reasons to fallback on all primitives. + */ +#define SAVAGE_FALLBACK_TEXTURE 0x1 +#define SAVAGE_FALLBACK_DRAW_BUFFER 0x2 +#define SAVAGE_FALLBACK_READ_BUFFER 0x4 +#define SAVAGE_FALLBACK_COLORMASK 0x8 +#define SAVAGE_FALLBACK_STIPPLE 0x10 +#define SAVAGE_FALLBACK_SPECULAR 0x20 +#define SAVAGE_FALLBACK_LOGICOP 0x40 +/*frank 2001/11/12 add the stencil fallbak*/ +#define SAVAGE_FALLBACK_STENCIL 0x80 +#define SAVAGE_FALLBACK_RENDERMODE 0x100 +#define SAVAGE_FALLBACK_BLEND_EQ 0x200 + + +#define HW_STENCIL 1 +#define HW_CULL 1 + +/* for savagectx.new_state - manage GL->driver state changes + */ +#define SAVAGE_NEW_TEXTURE 0x1 + + +/*define the max numer of vertex in vertex buf*/ +#define SAVAGE_MAX_VERTEXS 0x10000 + +/* Use the templated vertex formats: + */ +#define TAG(x) savage##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +typedef void (*savage_tri_func)( savageContextPtr, savageVertex *, + savageVertex *, savageVertex * ); +typedef void (*savage_line_func)( savageContextPtr, + savageVertex *, savageVertex * ); +typedef void (*savage_point_func)( savageContextPtr, savageVertex * ); + + +/************************************************************** + **************** enums for chip IDs ************************ + **************************************************************/ + +#define CHIP_S3GX3MS1NB 0x8A25 +#define CHIP_S3GX3MS1NBK 0x8A26 +#define CHIP_S3TWISTER 0x8D01 +#define CHIP_S3TWISTERK 0x8D02 +#define CHIP_S3TWISTER_P4M 0x8D04 +#define CHIP_S3PARAMOUNT128 0x8C22 /*SuperSavage 128/MX*/ +#define CHIP_S3TRISTAR128SDR 0x8C2A /*SuperSavage 128/IX*/ +#define CHIP_S3TRISTAR64SDRM7 0x8C2C /*SuperSavage/IX M7 Package*/ +#define CHIP_S3TRISTAR64SDR 0x8C2E /*SuperSavage/IX*/ +#define CHIP_S3TRISTAR64CDDR 0x8C2F /*SuperSavage/IXC DDR*/ + +#define IS_SAVAGE(imesa) (imesa->savageScreen->deviceID == CHIP_S3GX3MS1NB || \ + imesa->savageScreen->deviceID == CHIP_S3GX3MS1NBK || \ + imesa->savageScreen->deviceID == CHIP_S3TWISTER || \ + imesa->savageScreen->deviceID == CHIP_S3TWISTERK || \ + imesa->savageScreen->deviceID == CHIP_S3TWISTER_P4M || \ + imesa->savageScreen->deviceID == CHIP_S3PARAMOUNT128 || \ + imesa->savageScreen->deviceID == CHIP_S3TRISTAR128SDR || \ + imesa->savageScreen->deviceID == CHIP_S3TRISTAR64SDRM7 || \ + imesa->savageScreen->deviceID == CHIP_S3TRISTAR64SDR || \ + imesa->savageScreen->deviceID == CHIP_S3TRISTAR64CDDR ) + + + + +struct savage_context_t { + GLint refcount; + + GLcontext *glCtx; + + int lastTexHeap; + savageTextureObjectPtr CurrentTexObj[2]; + + struct savage_texture_object_t TexObjList[SAVAGE_NR_TEX_HEAPS]; + struct savage_texture_object_t SwappedOut; + + GLuint c_texupload; + GLuint c_texusage; + GLuint tex_thrash; + + GLuint TextureMode; + + + /* Hardware state + */ + + REGISTERS Registers; + + /* Manage our own state */ + GLuint new_state; + GLuint new_gl_state; + + GLuint BCIBase; + GLuint MMIO_BASE; + + /* DMA command buffer */ + DMABuffer_t DMABuf; + + /* aperture base */ + GLuint apertureBase[5]; + GLuint aperturePitch; + /* Manage hardware state */ + GLuint dirty; + memHeap_t *texHeap[SAVAGE_NR_TEX_HEAPS]; + GLuint bTexEn1; + /* One of the few bits of hardware state that can't be calculated + * completely on the fly: + */ + GLuint LcsCullMode; + + /* Rasterization state + */ + GLuint SetupNewInputs; + GLuint SetupIndex; + GLuint RenderIndex; + + GLuint hw_primitive; + GLenum raster_primitive; + GLenum render_primitive; + + GLubyte *verts; + GLuint vertex_format; + GLuint vertex_size; + GLuint DrawPrimitiveCmd; + GLuint DrawPrimitiveMask; + + /* Fallback rasterization functions + */ + savage_point_func draw_point; + savage_line_func draw_line; + savage_tri_func draw_tri; + + /* Funny mesa mirrors + */ + GLuint MonoColor; + GLuint ClearColor; + GLfloat depth_scale; + GLfloat hw_viewport[16]; + /* DRI stuff */ + drmBufPtr vertex_dma_buffer; + + GLframebuffer *glBuffer; + + /* Two flags to keep track of fallbacks. */ + GLuint Fallback; + + GLuint needClip; + + /* 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 */ + GLint currentClip; + XF86DRIClipRectPtr pClipRects; + + /* use this bit to support single/double buffer */ + GLuint IsDouble; + /* use this to indicate Fullscreen mode */ + GLuint IsFullScreen; + GLuint backup_frontOffset; + GLuint backup_backOffset; + GLuint backup_frontBitmapDesc; + GLuint toggle; + GLuint backup_streamFIFO; + GLuint NotFirstFrame; + + GLuint lastSwap; + GLuint secondLastSwap; + GLuint ctxAge; + GLuint dirtyAge; + GLuint any_contend; /* throttle me harder */ + + GLuint scissor; + drm_clip_rect_t draw_rect; + drm_clip_rect_t scissor_rect; + XF86DRIClipRectRec tmp_boxes[2][SAVAGE_NR_SAREA_CLIPRECTS]; + /*Texture aging and DMA based aging*/ + unsigned int texAge[SAVAGE_NR_TEX_HEAPS]; + + drmContext hHWContext; + drmLock *driHwLock; + GLuint driFd; + + __DRIdrawablePrivate *driDrawable; + __DRIdrawablePrivate *driReadable; + + /** + * Drawable used by Mesa for software fallbacks for reading and + * writing. It is set by Mesa's \c SetBuffer callback, and will always be + * either \c mga_context_t::driDrawable or \c mga_context_t::driReadable. + */ + __DRIdrawablePrivate *mesa_drawable; + + __DRIscreenPrivate *driScreen; + savageScreenPrivate *savageScreen; + drm_savage_sarea_t *sarea; + + GLboolean hw_stencil; + + /*shadow pointer*/ + volatile GLuint *shadowPointer; + volatile GLuint *eventTag1; + GLuint shadowCounter; + GLboolean shadowStatus; +}; + +#define SAVAGE_CONTEXT(ctx) ((savageContextPtr)(ctx->DriverCtx)) + +/* To remove all debugging, make sure SAVAGE_DEBUG is defined as a + * preprocessor symbol, and equal to zero. + */ +#define SAVAGE_DEBUG 0 +#ifndef SAVAGE_DEBUG +#warning "Debugging enabled - expect reduced performance" +extern int SAVAGE_DEBUG; +#endif + +#define DEBUG_VERBOSE_2D 0x1 +#define DEBUG_VERBOSE_RING 0x8 +#define DEBUG_VERBOSE_OUTREG 0x10 +#define DEBUG_ALWAYS_SYNC 0x40 +#define DEBUG_VERBOSE_MSG 0x80 +#define DEBUG_NO_OUTRING 0x100 +#define DEBUG_NO_OUTREG 0x200 +#define DEBUG_VERBOSE_API 0x400 +#define DEBUG_VALIDATE_RING 0x800 +#define DEBUG_VERBOSE_LRU 0x1000 +#define DEBUG_VERBOSE_DRI 0x2000 +#define DEBUG_VERBOSE_IOCTL 0x4000 + +#define TARGET_FRONT 0x0 +#define TARGET_BACK 0x1 +#define TARGET_DEPTH 0x2 + +#define SAVAGEDEBUG 0 +#define _SAVAGE_DEBUG +/*frank remove the least debug information*/ +#ifdef _SAVAGE_DEBUG +#define fprintf fprintf +#else +#define fprintf(...) +#endif + +#define SUBPIXEL_X -0.5 +#define SUBPIXEL_Y -0.375 + +#endif diff --git a/src/mesa/drivers/dri/savage/savagedd.c b/src/mesa/drivers/dri/savage/savagedd.c new file mode 100644 index 0000000000..96773e5a71 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagedd.c @@ -0,0 +1,106 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#include "mtypes.h" + +#include <stdio.h> + +#include "mm.h" +#include "savagedd.h" +#include "savagestate.h" +#include "savagespan.h" +#include "savagetex.h" +#include "savagetris.h" +#include "savagevb.h" +#include "savagecontext.h" +#include "extensions.h" + + +extern int xf86VTSema; + + +/*************************************** + * Mesa's Driver Functions + ***************************************/ + + +static const GLubyte *savageDDGetString( GLcontext *ctx, GLenum name ) +{ + switch (name) { + case GL_VENDOR: + return (GLubyte *)"S3 Graphics Inc."; + case GL_RENDERER: + return (GLubyte *)"Mesa DRI SAVAGE Linux_1.1.18"; + default: + return 0; + } +} +#if 0 +static GLint savageGetParameteri(const GLcontext *ctx, GLint param) +{ + switch (param) { + case DD_HAVE_HARDWARE_FOG: + return 1; + default: + return 0; + } +} +#endif + + +static void savageBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height) +{ + GET_CURRENT_CONTEXT(ctx); + savageContextPtr imesa = SAVAGE_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); +} + + + + +void savageDDExtensionsInit( GLcontext *ctx ) +{ + _mesa_enable_extension( ctx, "GL_ARB_multitexture" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_lod_bias" ); + _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); +} + + + + +void savageDDInitDriverFuncs( GLcontext *ctx ) +{ + ctx->Driver.GetBufferSize = savageBufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; + ctx->Driver.GetString = savageDDGetString; +} diff --git a/src/mesa/drivers/dri/savage/savagedd.h b/src/mesa/drivers/dri/savage/savagedd.h new file mode 100644 index 0000000000..8d058f3de1 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagedd.h @@ -0,0 +1,33 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#ifndef SAVAGEDD_INC +#define SAVAGEDD_INC + +#include "context.h" + +void savageDDExtensionsInit( GLcontext *ctx ); +void savageDDInitDriverFuncs( GLcontext *ctx ); +#endif diff --git a/src/mesa/drivers/dri/savage/savagedma.c b/src/mesa/drivers/dri/savage/savagedma.c new file mode 100644 index 0000000000..9b0bdc8b9f --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagedma.c @@ -0,0 +1,298 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + +#include <X11/Xlibint.h> +#include <stdio.h> +#include "savageioctl.h" +#include "savagedma.h" +#include "savage_bci.h" +#include <time.h> +#include <unistd.h> + +/* Commit does not depend on whether we use real DMA or fake it via the BCI */ +void savageDMACommit (savageContextPtr imesa, void *endPtr) { + DMABufferPtr dmaBuff = &imesa->DMABuf; + GLuint end = (GLuint)endPtr; + + /* make sure that enough space was allocated */ + assert (end <= dmaBuff->allocEnd); + + dmaBuff->allocEnd = dmaBuff->end = end; + + /* TODO: check commands, either here or in flush */ +} + +#if SAVAGE_CMD_DMA +/* flag = + 0 return -1 if no available page + 1 wait until a page be available */ +static GLuint getDMAPage (savageContextPtr imesa, int flag) { + DMABufferPtr dmaBuff = &imesa->DMABuf; + GLuint page; + GLuint eventTag1; + + if (dmaBuff->kickFlag == GL_FALSE) + return dmaBuff->usingPage; + + page = dmaBuff->usingPage + 1; + + /* overflow */ + if (page >= (dmaBuff->buf->size * dmaBuff->buf->type)/DMA_PAGE_SIZE) + page = 0; + + eventTag1 = GET_EVENTTAG; + if ( eventTag1 == page) { /* is kicking off */ + if (flag == 1) + while (GET_EVENTTAG == page); /* FIXME: add a max loop count? */ + else + return -1; + } + + /* ok, that's it */ + dmaBuff->usingPage = page; + dmaBuff->start = dmaBuff->end = dmaBuff->allocEnd = + (dmaBuff->buf->linear + DMA_PAGE_SIZE * page); + dmaBuff->kickFlag = GL_FALSE; + + return page; +} + +/* Allocate space in a real DMA buffer */ +void *savageDMAAlloc (savageContextPtr imesa, GLuint size) { + DMABufferPtr dmaBuff = &imesa->DMABuf; + + /* make sure that everything has been filled in and committed */ + assert (dmaBuff->end == dmaBuff->allocEnd); + + size *= sizeof (GLuint); /* size in bytes */ + if (dmaBuff->kickFlag == GL_TRUE) { + if (size > DMA_PAGE_SIZE) + return NULL; + getDMAPage (imesa, 1); + } else if (dmaBuff->end + size >= + dmaBuff->buf->linear + DMA_PAGE_SIZE*(dmaBuff->usingPage+1)) { + /* need kick off */ + savageDMAFlush (imesa); + getDMAPage (imesa, 1); + } + dmaBuff->allocEnd = dmaBuff->end + size; + return (void *)dmaBuff->end; +} + +/* Flush DMA buffer via DMA */ +void savageDMAFlush (savageContextPtr imesa) { + volatile GLuint* BCIbase; + DMABufferPtr dmaBuff = &imesa->DMABuf; + GLuint phyAddress; + GLuint dmaCount, dmaCount1, remain; + int i; + + /* make sure that everything has been filled in and committed */ + assert (dmaBuff->allocEnd == dmaBuff->end); + + if (dmaBuff->kickFlag == GL_TRUE) /* has been kicked off? */ + return; + if (dmaBuff->start == dmaBuff->end) /* no command? */ + return; + + /* get bci base */ + BCIbase = (volatile GLuint *)SAVAGE_GET_BCI_POINTER(imesa,4); + + /* set the eventtag */ + *BCIbase = (dmaBuff->usingPage & 0xffffL) | (CMD_UpdateShadowStat << 27) + | (1 << 22); + *BCIbase = 0x96010051; /* set register x51*/ + /* set the DMA buffer address */ + phyAddress = (dmaBuff->buf->phyaddress + dmaBuff->usingPage*DMA_PAGE_SIZE) + & MDT_SRCADD_ALIGMENT; + if (dmaBuff->buf->location == DRM_SAVAGE_MEM_LOCATION_AGP) + *BCIbase = (phyAddress) | MDT_SRC_AGP; + else + *BCIbase = (phyAddress) | MDT_SRC_PCI; + + /* pad with noops to multiple of 32 bytes */ + dmaCount = (GLuint)(dmaBuff->end - dmaBuff->start); + dmaCount1 = (dmaCount + 31UL) & ~31UL; + remain = (dmaCount1 - dmaCount) >> 2; + for (i = 0; i < remain; i++) { + *((GLuint *)dmaBuff->end) = 0x40000000L; + dmaBuff->end+=4; + } + dmaCount = (dmaCount1 >> 3) - 1; + dmaBuff->allocEnd = dmaBuff->end; + + /* kick off */ + *BCIbase = (0xA8000000L)|dmaCount; + dmaBuff->kickFlag = GL_TRUE; +} + +/* Init real DMA */ +int savageDMAInit (savageContextPtr imesa) +{ + DMABufferPtr dmaBuff = &imesa->DMABuf; + drm_savage_alloc_cont_mem_t * req; + int i; + long ret; + + req = (drm_savage_alloc_cont_mem_t *) + malloc (sizeof(drm_savage_alloc_cont_mem_t)); + if (!req) + return GL_FALSE; + + req->type = DRM_SAVAGE_MEM_PAGE; + req->linear = 0; + + /* try agp first */ + req->phyaddress = imesa->sarea->agp_offset; + if (req->phyaddress) { + if (drmMap (imesa->driFd, + req->phyaddress, + DRM_SAVAGE_DMA_AGP_SIZE, + (drmAddressPtr)&req->linear) < 0) { + fprintf (stderr, "AGP map error.\n"); + goto dma; + } + if (0) fprintf (stderr,"Using AGP dma|\n"); + req->location = DRM_SAVAGE_MEM_LOCATION_AGP; + req->size = DRM_SAVAGE_DMA_AGP_SIZE/DRM_SAVAGE_MEM_PAGE; + } + + dma: + if (!req->linear) { + req->size = DMA_BUFFER_SIZE/DRM_SAVAGE_MEM_PAGE; + for (i = 0; i < DMA_TRY_COUNT; i++) { + if ((ret = savageAllocDMABuffer (imesa, req)) != 0) + break; + req->size = req->size/2; + } + + if (ret <= 0) { + fprintf(stderr, "Can't alloc DMA memory(system and agp)\n"); + return GL_FALSE; + } + req->location = DRM_SAVAGE_MEM_LOCATION_PCI; + } + + dmaBuff->buf = req; + + dmaBuff->start = dmaBuff->end = dmaBuff->allocEnd = req->linear; + dmaBuff->usingPage = 0; + dmaBuff->kickFlag = GL_FALSE; + + return GL_TRUE; +} + +/* Close real DMA */ +int savageDMAClose (savageContextPtr imesa) +{ + DMABufferPtr dmaBuff = &imesa->DMABuf; + drm_savage_alloc_cont_mem_t * req = dmaBuff->buf; + + if(req->location == DRM_SAVAGE_MEM_LOCATION_PCI) + savageFreeDMABuffer (imesa, req); + else { /* AGP memory */ + drmUnmap ((drmAddress)req->linear, req->size*req->type); + drmRmMap (imesa->driFd, req->phyaddress); + } + free (req); + + return GL_TRUE; +} +#else +/* Allocate space in faked DMA buffer */ +void *savageDMAAlloc (savageContextPtr imesa, GLuint size) { + DMABufferPtr dmaBuff = &imesa->DMABuf; + + /* make sure that everything has been filled in and committed */ + assert (dmaBuff->end == dmaBuff->allocEnd); + + size *= sizeof (GLuint); /* size in bytes */ + if (dmaBuff->end + size >= dmaBuff->buf->linear + DMA_PAGE_SIZE) { + /* need kick off */ + savageDMAFlush (imesa); + } + dmaBuff->allocEnd = dmaBuff->end + size; + return (void *)dmaBuff->end; +} + +/* Flush DMA buffer via BCI (faked DMA) */ +void savageDMAFlush(savageContextPtr imesa) { + volatile GLuint* BCIbase; + DMABufferPtr dmaBuff = &imesa->DMABuf; + GLuint *entry; + + /* make sure that everything has been filled in and committed */ + assert (dmaBuff->allocEnd == dmaBuff->end); + + if (dmaBuff->start == dmaBuff->end) /* no command? */ + return; + + /* get bci base */ + BCIbase = (volatile GLuint *)SAVAGE_GET_BCI_POINTER( + imesa, (dmaBuff->end - dmaBuff->start) / sizeof (GLuint)); + + for (entry = (GLuint *)dmaBuff->start; + entry < (GLuint *)dmaBuff->end; ++entry) + *BCIbase = *entry; + + dmaBuff->end = dmaBuff->allocEnd = dmaBuff->start; +} + +/* Init faked DMA */ +int savageDMAInit (savageContextPtr imesa) { + DMABufferPtr dmaBuff = &imesa->DMABuf; + drm_savage_alloc_cont_mem_t * req; + + req = (drm_savage_alloc_cont_mem_t *) + malloc (sizeof(drm_savage_alloc_cont_mem_t)); + if (!req) + return GL_FALSE; + + req->linear = (GLuint)malloc (DMA_PAGE_SIZE); + if (!req->linear) { + free (req); + return GL_FALSE; + } + + dmaBuff->buf = req; + + dmaBuff->start = dmaBuff->end = dmaBuff->allocEnd = req->linear; + dmaBuff->usingPage = 0; + dmaBuff->kickFlag = GL_FALSE; + + return GL_TRUE; +} + +/* Close faked DMA */ +int savageDMAClose (savageContextPtr imesa) { + DMABufferPtr dmaBuff = &imesa->DMABuf; + drm_savage_alloc_cont_mem_t * req = dmaBuff->buf; + + free ((void *)req->linear); + free (req); + + return GL_TRUE; +} + +#endif diff --git a/src/mesa/drivers/dri/savage/savagedma.h b/src/mesa/drivers/dri/savage/savagedma.h new file mode 100644 index 0000000000..2945685846 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagedma.h @@ -0,0 +1,50 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#ifndef SAVAGEDMA +#define SAVAGEDMA + +/* Whether use DMA to transfer the 3d commands and data */ +#define SAVAGE_CMD_DMA 0 + +#define DMA_BUFFER_SIZE (4*1024*1024) /*4M*/ +#define MAX_DMA_BUFFER_SIZE (16*1024*1024) +#define DMA_PAGE_SIZE (4*1024) /* savage4 , twister, prosavage,...*/ +#define DMA_TRY_COUNT 4 + +#define MAX_SHADOWCOUNTER (MAX_DMA_BUFFER_SIZE / DMA_PAGE_SIZE) +typedef struct DMABuffer{ + drm_savage_alloc_cont_mem_t * buf; + GLuint start, end, allocEnd; + GLuint usingPage; /*current page */ + unsigned int kickFlag; /* usingPage is kicked off ?*/ +} DMABuffer_t, * DMABufferPtr; + +void *savageDMAAlloc (savageContextPtr imesa, GLuint size); +void savageDMACommit (savageContextPtr imesa, void *end); +void savageDMAFlush (savageContextPtr imesa); +int savageDMAInit (savageContextPtr imesa); +int savageDMAClose (savageContextPtr); +#endif diff --git a/src/mesa/drivers/dri/savage/savageioctl.c b/src/mesa/drivers/dri/savage/savageioctl.c new file mode 100644 index 0000000000..7f85ef920a --- /dev/null +++ b/src/mesa/drivers/dri/savage/savageioctl.c @@ -0,0 +1,521 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#include <stdio.h> +#include <unistd.h> +#include <sys/mman.h> + +#include "mtypes.h" +#include "macros.h" +#include "dd.h" +#include "context.h" +#include "swrast/swrast.h" + +#include "mm.h" +#include "savagecontext.h" +#include "savageioctl.h" +#include "savage_bci.h" +#include "savagedma.h" + +#include "drm.h" +#include <sys/ioctl.h> +#include <sys/timeb.h> + +extern GLuint bcicount; +#define DEPTH_SCALE_16 ((1<<16)-1) +#define DEPTH_SCALE_24 ((1<<24)-1) + +static void savage_BCI_clear(GLcontext *ctx, drm_savage_clear_t *pclear) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + int nbox = imesa->sarea->nbox; + drm_clip_rect_t *pbox = imesa->sarea->boxes; + int i; + + + if (nbox > SAVAGE_NR_SAREA_CLIPRECTS) + nbox = SAVAGE_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox ; i++, pbox++) { + unsigned int x = pbox->x1; + unsigned int y = pbox->y1; + unsigned int width = pbox->x2 - x+1; + unsigned int height = pbox->y2 - y+1; + unsigned int *bciptr; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > imesa->savageScreen->width || + pbox->y2 > imesa->savageScreen->height) + continue; + + if ( (pclear->flags & SAVAGE_FRONT) && imesa->IsFullScreen) { + bciptr = savageDMAAlloc (imesa, 8); + WRITE_CMD((bciptr) , 0x4BCC8C00,GLuint); + WRITE_CMD((bciptr) , imesa->savageScreen->frontOffset,GLuint); + WRITE_CMD((bciptr) , imesa->savageScreen->frontBitmapDesc,GLuint); + WRITE_CMD((bciptr) , pclear->clear_color,GLuint); + WRITE_CMD((bciptr) , (y <<16) | x,GLuint); + WRITE_CMD((bciptr) , (height << 16) | width,GLuint); + savageDMACommit (imesa, bciptr); + } + else if ( pclear->flags & (SAVAGE_BACK|SAVAGE_FRONT) ) { + bciptr = savageDMAAlloc (imesa, 8); + WRITE_CMD((bciptr) , 0x4BCC8C00,GLuint); + WRITE_CMD((bciptr) , imesa->savageScreen->backOffset,GLuint); + WRITE_CMD((bciptr) , imesa->savageScreen->backBitmapDesc,GLuint); + WRITE_CMD((bciptr) , pclear->clear_color,GLuint); + WRITE_CMD((bciptr) , (y <<16) | x,GLuint); + WRITE_CMD((bciptr) , (height << 16) | width,GLuint); + savageDMACommit (imesa, bciptr); + } + + if ( pclear->flags & (SAVAGE_DEPTH |SAVAGE_STENCIL) ) { + GLuint writeMask = 0x0; +#if HW_STENCIL + if(imesa->hw_stencil) + { + if(pclear->flags & SAVAGE_STENCIL) + { + + writeMask |= 0xFF000000; + } + if(pclear->flags & SAVAGE_DEPTH) + { + writeMask |= 0x00FFFFFF; + } + } +#endif + if(imesa->IsFullScreen && imesa->NotFirstFrame && + imesa->savageScreen->chipset >= S3_SAVAGE4) + { + imesa->Registers.ZBufCtrl.s4.autoZEnable = GL_TRUE; + imesa->Registers.ZBufCtrl.s4.frameID = ~imesa->Registers.ZBufCtrl.s4.frameID; + + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + else + { + if(imesa->IsFullScreen) + imesa->NotFirstFrame = GL_TRUE; + +#if HW_STENCIL + if(imesa->hw_stencil) + { + bciptr = savageDMAAlloc (imesa, 10); + if(writeMask != 0xFFFFFFFF) + { + WRITE_CMD((bciptr) , 0x960100D7,GLuint); + WRITE_CMD((bciptr) , writeMask,GLuint); + } + } + else +#endif + { + bciptr = savageDMAAlloc (imesa, 6); + } + + WRITE_CMD((bciptr) , 0x4BCC8C00,GLuint); + WRITE_CMD((bciptr) , imesa->savageScreen->depthOffset,GLuint); + WRITE_CMD((bciptr) , imesa->savageScreen->depthBitmapDesc,GLuint); + WRITE_CMD((bciptr) , pclear->clear_depth,GLuint); + WRITE_CMD((bciptr) , (y <<16) | x,GLuint); + WRITE_CMD((bciptr) , (height << 16) | width,GLuint); +#if HW_STENCIL + if(imesa->hw_stencil) + { + if(writeMask != 0xFFFFFFFF) + { + WRITE_CMD((bciptr) , 0x960100D7,GLuint); + WRITE_CMD((bciptr) , 0xFFFFFFFF,GLuint); + } + } +#endif + savageDMACommit (imesa, bciptr); + } + } + } + /* FK: Make sure that the clear stuff is emitted. Otherwise a + software fallback may get overwritten by a delayed clear. */ + savageDMAFlush (imesa); +} + +struct timeb a,b; + +static void savage_BCI_swap(savageContextPtr imesa) +{ + int nbox = imesa->sarea->nbox; + drm_clip_rect_t *pbox = imesa->sarea->boxes; + int i; + volatile unsigned int *bciptr; + + if (nbox > SAVAGE_NR_SAREA_CLIPRECTS) + nbox = SAVAGE_NR_SAREA_CLIPRECTS; + savageDMAFlush (imesa); + WAIT_IDLE_EMPTY; + + if(imesa->IsFullScreen) + { /* full screen*/ + unsigned int tmp0; + tmp0 = imesa->savageScreen->frontOffset; + imesa->savageScreen->frontOffset = imesa->savageScreen->backOffset; + imesa->savageScreen->backOffset = tmp0; + + if(imesa->toggle == TARGET_BACK) + imesa->toggle = TARGET_FRONT; + else + imesa->toggle = TARGET_BACK; + + imesa->drawMap = (char *)imesa->apertureBase[imesa->toggle]; + imesa->readMap = (char *)imesa->apertureBase[imesa->toggle]; + + imesa->Registers.DestCtrl.ni.offset = imesa->savageScreen->backOffset>>11; + imesa->Registers.changed.ni.fDestCtrlChanged = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + bciptr = SAVAGE_GET_BCI_POINTER(imesa,3); + *(bciptr) = 0x960100B0; + *(bciptr) = (imesa->savageScreen->frontOffset); + *(bciptr) = 0xA0000000; + } + + else + { /* Use bitblt copy from back to front buffer*/ + + for (i = 0 ; i < nbox; i++, pbox++) + { + unsigned int w = pbox->x2 - pbox->x1; + unsigned int h = pbox->y2 - pbox->y1; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > imesa->savageScreen->width || + pbox->y2 > imesa->savageScreen->height) + continue; + + bciptr = SAVAGE_GET_BCI_POINTER(imesa,6); + + *(bciptr) = 0x4BCC00C0; + + *(bciptr) = imesa->savageScreen->backOffset; + *(bciptr) = imesa->savageScreen->backBitmapDesc; + *(bciptr) = (pbox->y1 <<16) | pbox->x1; /*x0, y0*/ + *(bciptr) = (pbox->y1 <<16) | pbox->x1; + *(bciptr) = (h << 16) | w; + } + + } +} + + +static void savageDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + drm_savage_clear_t clear; + int i; + + clear.flags = 0; + clear.clear_color = imesa->ClearColor; + + if(imesa->savageScreen->zpp == 2) + clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_16); + else + clear.clear_depth = (GLuint) (ctx->Depth.Clear * DEPTH_SCALE_24); +#if 0 + FLUSH_BATCH( imesa ); +#endif + if ((mask & DD_FRONT_LEFT_BIT) && ((colorMask&0xffffffUL)==0xffffffUL) ){ + clear.flags |= SAVAGE_FRONT; + mask &= ~DD_FRONT_LEFT_BIT; + } + + if ((mask & DD_BACK_LEFT_BIT) && ((colorMask&0xffffffUL)==0xffffffUL) ) { + clear.flags |= SAVAGE_BACK; + mask &= ~DD_BACK_LEFT_BIT; + } + + if ((mask & DD_DEPTH_BIT) && ctx->Depth.Mask) { + clear.flags |= SAVAGE_DEPTH; + mask &= ~DD_DEPTH_BIT; + } + + if((mask & DD_STENCIL_BIT) && imesa->hw_stencil) + { + clear.flags |= SAVAGE_STENCIL; + mask &= ~DD_STENCIL_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 + SAVAGE_NR_SAREA_CLIPRECTS, imesa->numClipRects); + XF86DRIClipRectRec *box = imesa->pClipRects; + drm_clip_rect_t *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++ = *(drm_clip_rect_t *)&box[i]; + n++; + } + } + + imesa->sarea->nbox = n; + + savage_BCI_clear(ctx,&clear); + } + + UNLOCK_HARDWARE( imesa ); + imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS|SAVAGE_UPLOAD_CTX; + } + + if (mask) + _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); +} + + + + +/* + * Copy the back buffer to the front buffer. + */ +void savageSwapBuffers( __DRIdrawablePrivate *dPriv ) +{ + savageContextPtr imesa; + XF86DRIClipRectPtr pbox; + int nbox; + int i; + + GLboolean pending; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + imesa = (savageContextPtr) dPriv->driContextPriv->driverPrivate; + if (imesa->IsDouble) + _mesa_notifySwapBuffers( imesa->glCtx ); + + LOCK_HARDWARE( imesa ); + PAGE_PENDING(pending); + + if(!pending) + { + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + + for (i = 0 ; i < nbox ; ) + { + int nr = MIN2(i + SAVAGE_NR_SAREA_CLIPRECTS, dPriv->numClipRects); + XF86DRIClipRectRec *b = (XF86DRIClipRectRec *)imesa->sarea->boxes; + + imesa->sarea->nbox = nr - i; + + for ( ; i < nr ; i++) + *b++ = pbox[i]; + savage_BCI_swap(imesa) ; + } + } + UNLOCK_HARDWARE( imesa ); + + +} + +/* This waits for *everybody* to finish rendering -- overkill. + */ +void savageDmaFinish( savageContextPtr imesa ) +{ + savageDMAFlush(imesa); + WAIT_IDLE_EMPTY; +} + + +void savageRegetLockQuiescent( savageContextPtr imesa ) +{ + + +} + +void savageWaitAgeLocked( savageContextPtr imesa, int age ) +{ +} + + +void savageWaitAge( savageContextPtr imesa, int age ) +{ +} + + + +void savageFlushVertices( savageContextPtr imesa ) +{ + +} + + +void savageFlushVerticesLocked( savageContextPtr imesa ) +{ + +} + + +int savage_check_copy(int fd) +{ + return 0; +} + +static void savageDDFlush( GLcontext *ctx ) +{ + +} + +static void savageDDFinish( GLcontext *ctx ) +{ +} + +#define ALT_STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c60)) +#define STATUS_WORD0 (* (volatile GLuint *)(imesa->MMIO_BASE+0x48c00)) +#define MAXFIFO_S4 0x1FF00 +#define MAXFIFO_S3D 0x7F00 + +static GLboolean savagePagePending_s4( savageContextPtr imesa ) { + return (ALT_STATUS_WORD0 & 0x08000000) ? GL_TRUE : GL_FALSE; +} +static GLboolean savagePagePending_s3d( savageContextPtr imesa ) { + return GL_FALSE; +} +static void savageWaitForFIFO_s4( savageContextPtr imesa, unsigned count ) { + int loop = 0; + int slots = MAXFIFO_S4-count; + while((ALT_STATUS_WORD0 & 0x001fffff) > slots && loop++ < MAXLOOP); +} +static void savageWaitForFIFO_s3d( savageContextPtr imesa, unsigned count ) { + int loop = 0; + int slots = MAXFIFO_S3D-count; + while((STATUS_WORD0 & 0x0001ffff) > slots && loop++ < MAXLOOP); +} +static void savageWaitIdleEmpty_s4( savageContextPtr imesa ) { + int loop = 0; + while((ALT_STATUS_WORD0 & 0x00ffffff) != 0x00E00000L && loop++ < MAXLOOP); +} +static void savageWaitIdleEmpty_s3d( savageContextPtr imesa ) { + int loop = 0; + while((STATUS_WORD0 & 0x000fffff) != 0x000E0000L && loop++ < MAXLOOP); +} + +GLboolean (*savagePagePending)( savageContextPtr imesa ) = NULL; +void (*savageWaitForFIFO)( savageContextPtr imesa, unsigned count ) = NULL; +void (*savageWaitIdleEmpty)( savageContextPtr imesa ) = NULL; + + +void savageDDInitIoctlFuncs( GLcontext *ctx ) +{ + ctx->Driver.Clear = savageDDClear; + ctx->Driver.Flush = savageDDFlush; + ctx->Driver.Finish = savageDDFinish; + if (SAVAGE_CONTEXT( ctx )->savageScreen->chipset >= S3_SAVAGE4) { + savagePagePending = savagePagePending_s4; + savageWaitForFIFO = savageWaitForFIFO_s4; + savageWaitIdleEmpty = savageWaitIdleEmpty_s4; + } else { + savagePagePending = savagePagePending_s3d; + savageWaitForFIFO = savageWaitForFIFO_s3d; + savageWaitIdleEmpty = savageWaitIdleEmpty_s3d; + } +} + +#if SAVAGE_CMD_DMA +/* Alloc a continuous memory */ +/* return: 0 error when kernel alloc pages(can try a half memory size) + >0 sucess + <0 Other error*/ +int savageAllocDMABuffer(savageContextPtr imesa, drm_savage_alloc_cont_mem_t *req) +{ + int ret; + if (req ==NULL) + return 0; + + if ((ret=ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_ALLOC_CONTINUOUS_MEM, req)) <=0) + return ret; + + return 1; + +} + +/* get the physics address*/ +GLuint savageGetPhyAddress(savageContextPtr imesa,void * pointer) +{ + + drm_savage_get_physcis_address_t req; + int ret; + + req.v_address = (GLuint )pointer; + ret = ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_GET_PHYSICS_ADDRESS,&req); + + return req.p_address; +} + +/* free the buffer got by savageAllocDMABuffe*/ +int savageFreeDMABuffer(savageContextPtr imesa, drm_savage_alloc_cont_mem_t *req) +{ + GLuint ret; + if (req ==NULL) + return 0; + + if ((ret=ioctl(imesa->driFd, DRM_IOCTL_SAVAGE_FREE_CONTINUOUS_MEM, req)) <=0) + return ret; + return 1; + +} +#endif diff --git a/src/mesa/drivers/dri/savage/savageioctl.h b/src/mesa/drivers/dri/savage/savageioctl.h new file mode 100644 index 0000000000..94b02e3319 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savageioctl.h @@ -0,0 +1,72 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#ifndef SAVAGE_IOCTL_H +#define SAVAGE_IOCTL_H + +#include "savagecontext.h" +#include "savagedma.h" + +void savageGetGeneralDmaBufferLocked( savageContextPtr mmesa ); + +void savageFlushVertices( savageContextPtr mmesa ); +void savageFlushVerticesLocked( savageContextPtr mmesa ); + +void savageFlushGeneralLocked( savageContextPtr imesa ); +void savageWaitAgeLocked( savageContextPtr imesa, int age ); +void savageWaitAge( savageContextPtr imesa, int age ); + +void savageDmaFinish( savageContextPtr imesa ); + +void savageRegetLockQuiescent( savageContextPtr imesa ); + +void savageDDInitIoctlFuncs( GLcontext *ctx ); + +void savageSwapBuffers( __DRIdrawablePrivate *dPriv ); + +int savage_check_copy(int fd); + +extern GLboolean (*savagePagePending)( savageContextPtr imesa ); +extern void (*savageWaitForFIFO)( savageContextPtr imesa, unsigned count ); +extern void (*savageWaitIdleEmpty)( savageContextPtr imesa ); + +#define PAGE_PENDING(result) do { \ + result = savagePagePending(imesa); \ +} while (0) +#define WAIT_FOR_FIFO(count) do { \ + savageWaitForFIFO(imesa, count); \ +} while (0) +#define WAIT_IDLE_EMPTY do { \ + savageWaitIdleEmpty(imesa); \ +} while (0) + +#if SAVAGE_CMD_DMA +int savageAllocDMABuffer(savageContextPtr imesa, drm_savage_alloc_cont_mem_t *req); +GLuint savageGetPhyAddress(savageContextPtr imesa,void * pointer); +int savageFreeDMABuffer(savageContextPtr, drm_savage_alloc_cont_mem_t*); +#endif + +#define FLUSH_BATCH(imesa) savageDMAFlush(imesa) +#endif diff --git a/src/mesa/drivers/dri/savage/savagespan.c b/src/mesa/drivers/dri/savage/savagespan.c new file mode 100644 index 0000000000..aa13cfcb1d --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagespan.c @@ -0,0 +1,313 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + +#include "mtypes.h" +#include "savagedd.h" +#include "savagespan.h" +#include "savageioctl.h" +#include "savage_bci.h" +#include "savage_3d_reg.h" +#include "swrast/swrast.h" + +#define DBG 0 + +#define LOCAL_VARS \ + __DRIdrawablePrivate *dPriv = imesa->mesa_drawable; \ + savageScreenPrivate *savageScreen = imesa->savageScreen; \ + GLuint cpp = savageScreen->cpp; \ + GLuint pitch = imesa->aperturePitch; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(imesa->drawMap + \ + dPriv->x * cpp + \ + dPriv->y * pitch); \ + char *read_buf = (char *)(imesa->readMap + \ + dPriv->x * cpp + \ + dPriv->y * pitch); \ + GLuint p = SAVAGE_CONTEXT( ctx )->MonoColor; \ + (void) read_buf; (void) buf; (void) p + +#define LOCAL_DEPTH_VARS \ + __DRIdrawablePrivate *dPriv = imesa->mesa_drawable; \ + savageScreenPrivate *savageScreen = imesa->savageScreen; \ + GLuint zpp = savageScreen->zpp; \ + GLuint pitch = imesa->aperturePitch; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(imesa->apertureBase[TARGET_DEPTH] + \ + dPriv->x * zpp + \ + dPriv->y * pitch) + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + +#define INIT_MONO_PIXEL(p) + +#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() savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \ + WAIT_IDLE_EMPTY;\ + +#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) + +#if 0 +#define HW_UNLOCK() \ + UNLOCK_HARDWARE(imesa); +#endif +#define HW_UNLOCK() { } + + +/* 16 bit, 565 rgb color spanline and pixel functions + */ +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = SAVAGEPACKCOLOR565( color[0], color[1], color[2] ) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ +do{ \ + *(GLushort *)(buf + (_x<<1) + _y*pitch) = ( (((int)r & 0xf8) << 8) |\ + (((int)g & 0xfc) << 3) | \ + (((int)b & 0xf8) >> 3)); \ +}while(0) +#define WRITE_PIXEL( _x, _y, p ) \ +do{ \ + *(GLushort *)(buf + (_x<<1) + _y*pitch) = p; \ +}while(0) + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLushort p = *(GLushort *)(read_buf + (_x<<1) + _y*pitch); \ + rgba[0] = (((p >> 11) & 0x1f) * 255) >>5; \ + rgba[1] = (((p >> 5) & 0x3f) * 255) >>6; \ + rgba[2] = (((p >> 0) & 0x1f) * 255) >>5; \ + rgba[3] = 255; \ +} while(0) + +#define TAG(x) savage##x##_565 +#include "spantmp.h" + + +/* 32 bit, 8888 ARGB color spanline and pixel functions + */ +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = SAVAGEPACKCOLOR8888( color[0], color[1], color[2], color[3] ) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLuint *)(buf + (_x<<2) + _y*pitch) = ( ((GLuint)a << 24) | \ + ((GLuint)r << 16) | \ + ((GLuint)g << 8) | \ + ((GLuint)b )) +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLuint *)(buf + (_x<<2) + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLuint p = *(GLuint *)(read_buf + (_x<<2) + _y*pitch); \ + rgba[0] = (p >> 16) & 0xFF; \ + rgba[1] = (p >> 8) & 0xFF; \ + rgba[2] = (p >> 0) & 0xFF; \ + rgba[3] = 0xFF; \ +} while(0) + +#define TAG(x) savage##x##_8888 +#include "spantmp.h" + + + + +/* 16 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ +do{ \ + *(GLushort *)(buf + (_x<<1) + _y*pitch) = d; \ +}while(0) + +#define READ_DEPTH( d, _x, _y ) \ +do{ \ + d = *(GLushort *)(buf + (_x<<1) + _y*pitch); \ +}while(0) + +/* d = 0xffff; */ + +#define TAG(x) savage##x##_16 +#include "depthtmp.h" + + + + + +/* 8-bit stencil /24-bit depth depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) { \ + GLuint tmp = *(GLuint *)(buf + (_x<<2) + _y*pitch); \ + tmp &= 0xFF000000; \ + tmp |= d; \ + *(GLuint *)(buf + (_x<<2) + _y*pitch) = tmp; \ +} + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + (_x<<2) + _y*pitch) & 0x00FFFFFF; + +/* d = 0x00ffffff; */ + +#define TAG(x) savage##x##_8_24 +#include "depthtmp.h" + + +#define WRITE_STENCIL( _x, _y, d ) { \ + GLuint tmp = *(GLuint *)(buf + (_x<<2) + _y*pitch); \ + tmp &= 0x00FFFFFF; \ + tmp |= (((GLuint)d)<<24) & 0xFF000000; \ + *(GLuint *)(buf + (_x<<2) + _y*pitch) = tmp; \ +} + +#define READ_STENCIL( d, _x, _y ) \ + d = (GLstencil)((*(GLuint *)(buf + (_x<<2) + _y*pitch) & 0xFF000000) >> 24); + +#define TAG(x) savage##x##_8_24 +#include "stenciltmp.h" + + +/* + * This function is called to specify which buffer to read and write + * for software rasterization (swrast) fallbacks. This doesn't necessarily + * correspond to glDrawBuffer() or glReadBuffer() calls. + */ +static void savageDDSetBuffer(GLcontext *ctx, GLframebuffer *buffer, + GLuint bufferBit) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + char *map; + + assert( (bufferBit == FRONT_LEFT_BIT) || (bufferBit == BACK_LEFT_BIT) ); + + map = (bufferBit == FRONT_LEFT_BIT) + ? (char*)imesa->apertureBase[TARGET_FRONT] + : (char*)imesa->apertureBase[TARGET_BACK]; + + imesa->drawMap = map; + imesa->readMap = map; + + assert( (buffer == imesa->driDrawable->driverPrivate) + || (buffer == imesa->driReadable->driverPrivate) ); + + imesa->mesa_drawable = (buffer == imesa->driDrawable->driverPrivate) + ? imesa->driDrawable : imesa->driReadable; +} + + +void savageDDInitSpanFuncs( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + + swdd->SetBuffer = savageDDSetBuffer; + + switch (imesa->savageScreen->cpp) + { + case 2: + swdd->WriteRGBASpan = savageWriteRGBASpan_565; + swdd->WriteRGBSpan = savageWriteRGBSpan_565; + swdd->WriteMonoRGBASpan = savageWriteMonoRGBASpan_565; + swdd->WriteRGBAPixels = savageWriteRGBAPixels_565; + swdd->WriteMonoRGBAPixels = savageWriteMonoRGBAPixels_565; + swdd->ReadRGBASpan = savageReadRGBASpan_565; + swdd->ReadRGBAPixels = savageReadRGBAPixels_565; + + break; + + case 4: + swdd->WriteRGBASpan = savageWriteRGBASpan_8888; + swdd->WriteRGBSpan = savageWriteRGBSpan_8888; + swdd->WriteMonoRGBASpan = savageWriteMonoRGBASpan_8888; + swdd->WriteRGBAPixels = savageWriteRGBAPixels_8888; + swdd->WriteMonoRGBAPixels = savageWriteMonoRGBAPixels_8888; + swdd->ReadRGBASpan = savageReadRGBASpan_8888; + swdd->ReadRGBAPixels = savageReadRGBAPixels_8888; + } + + switch (imesa->savageScreen->zpp) + { + case 2: + swdd->ReadDepthSpan = savageReadDepthSpan_16; + swdd->WriteDepthSpan = savageWriteDepthSpan_16; + swdd->ReadDepthPixels = savageReadDepthPixels_16; + swdd->WriteDepthPixels = savageWriteDepthPixels_16; + + break; + case 4: + swdd->ReadDepthSpan = savageReadDepthSpan_8_24; + swdd->WriteDepthSpan = savageWriteDepthSpan_8_24; + swdd->ReadDepthPixels = savageReadDepthPixels_8_24; + swdd->WriteDepthPixels = savageWriteDepthPixels_8_24; +#if HW_STENCIL + swdd->ReadStencilSpan = savageReadStencilSpan_8_24; + swdd->WriteStencilSpan = savageWriteStencilSpan_8_24; + swdd->ReadStencilPixels = savageReadStencilPixels_8_24; + swdd->WriteStencilPixels = savageWriteStencilPixels_8_24; +#endif + break; + + } + swdd->WriteCI8Span =NULL; + swdd->WriteCI32Span =NULL; + swdd->WriteMonoCISpan =NULL; + swdd->WriteCI32Pixels =NULL; + swdd->WriteMonoCIPixels =NULL; + swdd->ReadCI32Span =NULL; + swdd->ReadCI32Pixels =NULL; + + /* 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; +} diff --git a/src/mesa/drivers/dri/savage/savagespan.h b/src/mesa/drivers/dri/savage/savagespan.h new file mode 100644 index 0000000000..35247b4706 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagespan.h @@ -0,0 +1,30 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + +#ifndef _SAVAGE_SPAN_H +#define _SAVAGE_SPAN_H + +extern void savageDDInitSpanFuncs( GLcontext *ctx ); + +#endif diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c new file mode 100644 index 0000000000..622e4362ab --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagestate.c @@ -0,0 +1,2444 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#include <stdio.h> + +#include "mtypes.h" +#include "enums.h" +#include "macros.h" +#include "dd.h" + +#include "mm.h" +#include "savagedd.h" +#include "savagecontext.h" + +#include "savagestate.h" +#include "savagetex.h" +#include "savagevb.h" +#include "savagetris.h" +#include "savageioctl.h" +#include "savage_bci.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +static void savageBlendFunc_s4(GLcontext *); +static void savageBlendFunc_s3d(GLcontext *); + +static __inline__ GLuint savagePackColor(GLuint format, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + switch (format) { + case DV_PF_8888: + return SAVAGEPACKCOLOR8888(r,g,b,a); + case DV_PF_565: + return SAVAGEPACKCOLOR565(r,g,b); + default: + + return 0; + } +} + + +static void savageDDAlphaFunc_s4(GLcontext *ctx, GLenum func, GLfloat ref) +{ + /* This can be done in BlendFunc*/ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + imesa->dirty |= SAVAGE_UPLOAD_CTX; + savageBlendFunc_s4(ctx); +} +static void savageDDAlphaFunc_s3d(GLcontext *ctx, GLenum func, GLfloat ref) +{ + /* This can be done in BlendFunc*/ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + imesa->dirty |= SAVAGE_UPLOAD_CTX; + savageBlendFunc_s3d(ctx); +} + +static void savageDDBlendEquationSeparate(GLcontext *ctx, + GLenum modeRGB, GLenum modeA) +{ + assert( modeRGB == modeA ); + + /* BlendEquation sets ColorLogicOpEnabled in an unexpected + * manner. + */ + FALLBACK( ctx, SAVAGE_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); + + /* Can only do blend addition, not min, max, subtract, etc. */ + FALLBACK( ctx, SAVAGE_FALLBACK_BLEND_EQ, + modeRGB != GL_FUNC_ADD); +} + + +static void savageBlendFunc_s4(GLcontext *ctx) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + Reg_DrawLocalCtrl DrawLocalCtrl; + + /* set up draw control register (including blending, alpha + * test, dithering, and shading model) + */ + + /* + * And mask removes flushPdDestWrites + */ + + DrawLocalCtrl.ui = imesa->Registers.DrawLocalCtrl.ui & ~0x40000000; + + /* + * blend modes + */ + if(ctx->Color.BlendEnabled){ + switch (ctx->Color.BlendDstRGB) + { + case GL_ZERO: + DrawLocalCtrl.ni.dstAlphaMode = DAM_Zero; + break; + + case GL_ONE: + DrawLocalCtrl.ni.dstAlphaMode = DAM_One; + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_SRC_COLOR: + DrawLocalCtrl.ni.dstAlphaMode = DAM_SrcClr; + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_ONE_MINUS_SRC_COLOR: + DrawLocalCtrl.ni.dstAlphaMode = DAM_1SrcClr; + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_SRC_ALPHA: + DrawLocalCtrl.ni.dstAlphaMode = DAM_SrcAlpha; + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_ONE_MINUS_SRC_ALPHA: + DrawLocalCtrl.ni.dstAlphaMode = DAM_1SrcAlpha; + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_DST_ALPHA: + if (imesa->glCtx->Visual.alphaBits == 0) + { + DrawLocalCtrl.ni.dstAlphaMode = DAM_One; + } + else + { + DrawLocalCtrl.ni.dstAlphaMode = DAM_DstAlpha; + } + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_ONE_MINUS_DST_ALPHA: + if (imesa->glCtx->Visual.alphaBits == 0) + { + DrawLocalCtrl.ni.dstAlphaMode = DAM_Zero; + } + else + { + DrawLocalCtrl.ni.dstAlphaMode = DAM_1DstAlpha; + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + } + break; + } + + switch (ctx->Color.BlendSrcRGB) + { + case GL_ZERO: + DrawLocalCtrl.ni.srcAlphaMode = SAM_Zero; + break; + + case GL_ONE: + DrawLocalCtrl.ni.srcAlphaMode = SAM_One; + break; + + case GL_DST_COLOR: + DrawLocalCtrl.ni.srcAlphaMode = SAM_DstClr; + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_ONE_MINUS_DST_COLOR: + DrawLocalCtrl.ni.srcAlphaMode = SAM_1DstClr; + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_SRC_ALPHA: + DrawLocalCtrl.ni.srcAlphaMode = SAM_SrcAlpha; + break; + + case GL_ONE_MINUS_SRC_ALPHA: + DrawLocalCtrl.ni.srcAlphaMode = SAM_1SrcAlpha; + break; + + case GL_DST_ALPHA: + if (imesa->glCtx->Visual.alphaBits == 0) + { + DrawLocalCtrl.ni.srcAlphaMode = SAM_One; + } + else + { + DrawLocalCtrl.ni.srcAlphaMode = SAM_DstAlpha; + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + } + break; + + case GL_ONE_MINUS_DST_ALPHA: + if (imesa->glCtx->Visual.alphaBits == 0) + { + DrawLocalCtrl.ni.srcAlphaMode = SAM_Zero; + } + else + { + DrawLocalCtrl.ni.srcAlphaMode = SAM_1DstAlpha; + DrawLocalCtrl.ni.flushPdDestWrites = GL_TRUE; + } + break; + } + } + else + { + DrawLocalCtrl.ni.dstAlphaMode = DAM_Zero; + DrawLocalCtrl.ni.srcAlphaMode = SAM_One; + } + + /* alpha test*/ + + if(ctx->Color.AlphaEnabled) + { + int a; + GLubyte alphaRef; + + CLAMPED_FLOAT_TO_UBYTE(alphaRef,ctx->Color.AlphaRef); + + switch(ctx->Color.AlphaFunc) { + case GL_NEVER: a = LCS_A_NEVER; break; + case GL_ALWAYS: a = LCS_A_ALWAYS; break; + case GL_LESS: a = LCS_A_LESS; break; + case GL_LEQUAL: a = LCS_A_LEQUAL; break; + case GL_EQUAL: a = LCS_A_EQUAL; break; + case GL_GREATER: a = LCS_A_GREATER; break; + case GL_GEQUAL: a = LCS_A_GEQUAL; break; + case GL_NOTEQUAL: a = LCS_A_NOTEQUAL; break; + default:return; + } + + if (imesa->Registers.DrawCtrl1.ni.alphaTestEn != GL_TRUE) + { + imesa->Registers.DrawCtrl1.ni.alphaTestEn = GL_TRUE; + imesa->Registers.changed.ni.fDrawCtrl1Changed = GL_TRUE; + } + + if (imesa->Registers.DrawCtrl1.ni.alphaTestCmpFunc != + (a & 0x0F)) + { + imesa->Registers.DrawCtrl1.ni.alphaTestCmpFunc = + a & 0x0F; + imesa->Registers.changed.ni.fDrawCtrl1Changed = GL_TRUE; + } + + /* looks like rounding control is different on katmai than p2*/ + + if (imesa->Registers.DrawCtrl0.ni.alphaRefVal != alphaRef) + { + imesa->Registers.DrawCtrl0.ni.alphaRefVal = alphaRef; + imesa->Registers.changed.ni.fDrawCtrl0Changed = GL_TRUE; + } + } + else + { + if (imesa->Registers.DrawCtrl1.ni.alphaTestEn != GL_FALSE) + { + imesa->Registers.DrawCtrl1.ni.alphaTestEn = GL_FALSE; + imesa->Registers.changed.ni.fDrawCtrl1Changed = GL_TRUE; + } + } + + /* Set/Reset Z-after-alpha*/ + + DrawLocalCtrl.ni.wrZafterAlphaTst = imesa->Registers.DrawCtrl1.ni.alphaTestEn; + /*DrawLocalCtrl.ni.zUpdateEn = ~DrawLocalCtrl.ni.wrZafterAlphaTst;*/ + + if (imesa->Registers.DrawLocalCtrl.ui != DrawLocalCtrl.ui) + { + imesa->Registers.DrawLocalCtrl.ui = DrawLocalCtrl.ui; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + } + + /* dithering*/ + + if ( ctx->Color.DitherFlag ) + { + if (imesa->Registers.DrawCtrl1.ni.ditherEn != GL_TRUE) + { + imesa->Registers.DrawCtrl1.ni.ditherEn = GL_TRUE; + imesa->Registers.changed.ni.fDrawCtrl1Changed = GL_TRUE; + } + } + else + { + if (imesa->Registers.DrawCtrl1.ni.ditherEn != GL_FALSE) + { + imesa->Registers.DrawCtrl1.ni.ditherEn = GL_FALSE; + imesa->Registers.changed.ni.fDrawCtrl1Changed = GL_TRUE; + } + } +} +static void savageBlendFunc_s3d(GLcontext *ctx) +{ + + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + Reg_DrawCtrl DrawCtrl; + + /* set up draw control register (including blending, alpha + * test, dithering, and shading model) + */ + + /* + * And mask removes flushPdDestWrites + */ + + DrawCtrl.ui = imesa->Registers.DrawCtrl.ui & ~0x20000000; + + /* + * blend modes + */ + if(ctx->Color.BlendEnabled){ + switch (ctx->Color.BlendDstRGB) + { + case GL_ZERO: + DrawCtrl.ni.dstAlphaMode = DAM_Zero; + break; + + case GL_ONE: + DrawCtrl.ni.dstAlphaMode = DAM_One; + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_SRC_COLOR: + DrawCtrl.ni.dstAlphaMode = DAM_SrcClr; + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_ONE_MINUS_SRC_COLOR: + DrawCtrl.ni.dstAlphaMode = DAM_1SrcClr; + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_SRC_ALPHA: + DrawCtrl.ni.dstAlphaMode = DAM_SrcAlpha; + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_ONE_MINUS_SRC_ALPHA: + DrawCtrl.ni.dstAlphaMode = DAM_1SrcAlpha; + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_DST_ALPHA: + if (imesa->glCtx->Visual.alphaBits == 0) + { + DrawCtrl.ni.dstAlphaMode = DAM_One; + } + else + { + DrawCtrl.ni.dstAlphaMode = DAM_DstAlpha; + } + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_ONE_MINUS_DST_ALPHA: + if (imesa->glCtx->Visual.alphaBits == 0) + { + DrawCtrl.ni.dstAlphaMode = DAM_Zero; + } + else + { + DrawCtrl.ni.dstAlphaMode = DAM_1DstAlpha; + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + } + break; + } + + switch (ctx->Color.BlendSrcRGB) + { + case GL_ZERO: + DrawCtrl.ni.srcAlphaMode = SAM_Zero; + break; + + case GL_ONE: + DrawCtrl.ni.srcAlphaMode = SAM_One; + break; + + case GL_DST_COLOR: + DrawCtrl.ni.srcAlphaMode = SAM_DstClr; + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_ONE_MINUS_DST_COLOR: + DrawCtrl.ni.srcAlphaMode = SAM_1DstClr; + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + break; + + case GL_SRC_ALPHA: + DrawCtrl.ni.srcAlphaMode = SAM_SrcAlpha; + break; + + case GL_ONE_MINUS_SRC_ALPHA: + DrawCtrl.ni.srcAlphaMode = SAM_1SrcAlpha; + break; + + case GL_DST_ALPHA: + if (imesa->glCtx->Visual.alphaBits == 0) + { + DrawCtrl.ni.srcAlphaMode = SAM_One; + } + else + { + DrawCtrl.ni.srcAlphaMode = SAM_DstAlpha; + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + } + break; + + case GL_ONE_MINUS_DST_ALPHA: + if (imesa->glCtx->Visual.alphaBits == 0) + { + DrawCtrl.ni.srcAlphaMode = SAM_Zero; + } + else + { + DrawCtrl.ni.srcAlphaMode = SAM_1DstAlpha; + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + } + break; + } + } + else + { + DrawCtrl.ni.dstAlphaMode = DAM_Zero; + DrawCtrl.ni.srcAlphaMode = SAM_One; + } + + /* alpha test*/ + + if(ctx->Color.AlphaEnabled) + { + GLint a; + GLubyte alphaRef; + + CLAMPED_FLOAT_TO_UBYTE(alphaRef,ctx->Color.AlphaRef); + + switch(ctx->Color.AlphaFunc) { + case GL_NEVER: a = LCS_A_NEVER; break; + case GL_ALWAYS: a = LCS_A_ALWAYS; break; + case GL_LESS: a = LCS_A_LESS; break; + case GL_LEQUAL: a = LCS_A_LEQUAL; break; + case GL_EQUAL: a = LCS_A_EQUAL; break; + case GL_GREATER: a = LCS_A_GREATER; break; + case GL_GEQUAL: a = LCS_A_GEQUAL; break; + case GL_NOTEQUAL: a = LCS_A_NOTEQUAL; break; + default:return; + } + + DrawCtrl.ni.alphaTestEn = GL_TRUE; + DrawCtrl.ni.alphaTestCmpFunc = a & 0x07; + DrawCtrl.ni.alphaRefVal = alphaRef; + } + else + { + DrawCtrl.ni.alphaTestEn = GL_FALSE; + } + + /* Set/Reset Z-after-alpha*/ + + if (imesa->Registers.ZBufCtrl.s3d.wrZafterAlphaTst != + DrawCtrl.ni.alphaTestEn) + { + imesa->Registers.ZBufCtrl.s3d.wrZafterAlphaTst = + DrawCtrl.ni.alphaTestEn; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + } + /*DrawLocalCtrl.ni.zUpdateEn = ~DrawLocalCtrl.ni.wrZafterAlphaTst;*/ + + /* dithering*/ + + if ( ctx->Color.DitherFlag ) + { + DrawCtrl.ni.ditherEn = GL_TRUE; + } + else + { + DrawCtrl.ni.ditherEn = GL_FALSE; + } + + if (imesa->Registers.DrawCtrl.ui != DrawCtrl.ui) + { + imesa->Registers.DrawCtrl.ui = DrawCtrl.ui; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; + } +} + +static void savageDDBlendFuncSeparate_s4( GLcontext *ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, + GLenum dfactorA ) +{ + assert (dfactorRGB == dfactorA && sfactorRGB == sfactorA); + savageBlendFunc_s4( ctx ); +} +static void savageDDBlendFuncSeparate_s3d( GLcontext *ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, + GLenum dfactorA ) +{ + assert (dfactorRGB == dfactorA && sfactorRGB == sfactorA); + savageBlendFunc_s3d( ctx ); +} + + + +static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + int zmode; +#define depthIndex 0 + + /* set up z-buffer control register (global) + * set up z-buffer offset register (global) + * set up z read/write watermarks register (global) + */ + + 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; + } + if (ctx->Depth.Test) + { + + if (imesa->Registers.ZBufCtrl.s4.zCmpFunc != (zmode & 0x0F)) + { + imesa->Registers.ZBufCtrl.s4.zCmpFunc = zmode & 0x0F; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + } + + if (imesa->Registers.DrawLocalCtrl.ni.zUpdateEn != ctx->Depth.Mask) + { + imesa->Registers.DrawLocalCtrl.ni.zUpdateEn = ctx->Depth.Mask; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + } + + if (imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites == GL_FALSE) + { + imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; +#if 1 + imesa->Registers.ZWatermarks.ni.wLow = 0; + imesa->Registers.changed.ni.fZWatermarksChanged = GL_TRUE; +#endif + } + + if (imesa->Registers.ZBufCtrl.s4.zBufEn != GL_TRUE) + { + imesa->Registers.ZBufCtrl.s4.zBufEn = GL_TRUE; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + } + } + else if (imesa->glCtx->Stencil.Enabled && + !imesa->glCtx->DrawBuffer->UseSoftwareStencilBuffer) + { +#define STENCIL (0x27) + + /* by Jiayo, tempory disable HW stencil in 24 bpp */ +#if HW_STENCIL + if(imesa->hw_stencil) + { + if ((imesa->Registers.ZBufCtrl.ui & STENCIL) != STENCIL) + { + imesa->Registers.ZBufCtrl.s4.zCmpFunc = GL_ALWAYS & 0x0F; + imesa->Registers.ZBufCtrl.s4.zBufEn = GL_TRUE; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + } + + if (imesa->Registers.DrawLocalCtrl.ni.zUpdateEn != GL_FALSE) + { + imesa->Registers.DrawLocalCtrl.ni.zUpdateEn = GL_FALSE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + } + + if (imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites == GL_TRUE) + { + imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + + imesa->Registers.ZWatermarks.ni.wLow = 8; + imesa->Registers.changed.ni.fZWatermarksChanged = GL_TRUE; + } + } +#endif /* end #if HW_STENCIL */ + } + else + { + + if (imesa->Registers.DrawLocalCtrl.ni.drawUpdateEn == GL_FALSE) + { + imesa->Registers.ZBufCtrl.s4.zCmpFunc = LCS_Z_ALWAYS & 0x0F; + imesa->Registers.ZBufCtrl.s4.zBufEn = GL_TRUE; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + + if (imesa->Registers.DrawLocalCtrl.ni.zUpdateEn != GL_FALSE) + { + imesa->Registers.DrawLocalCtrl.ni.zUpdateEn = GL_FALSE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + } + + if (imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites == GL_TRUE) + { + imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + + imesa->Registers.ZWatermarks.ni.wLow = 8; + imesa->Registers.changed.ni.fZWatermarksChanged = GL_TRUE; + + } + } + else + + /* DRAWUPDATE_REQUIRES_Z_ENABLED*/ + { + if (imesa->Registers.ZBufCtrl.s4.zBufEn != GL_FALSE) + { + imesa->Registers.ZBufCtrl.s4.zBufEn = GL_FALSE; + imesa->Registers.DrawLocalCtrl.ni.zUpdateEn = GL_FALSE; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE; + imesa->Registers.ZWatermarks.ni.wLow = 8; + imesa->Registers.changed.ni.fZWatermarksChanged = GL_TRUE; + } + } + } + + imesa->dirty |= SAVAGE_UPLOAD_CTX; +} +static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + Reg_ZBufCtrl ZBufCtrl; + int zmode; +#define depthIndex 0 + + /* set up z-buffer control register (global) + * set up z-buffer offset register (global) + * set up z read/write watermarks register (global) + */ + ZBufCtrl.ui = imesa->Registers.ZBufCtrl.ui; + + 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; + } + if (ctx->Depth.Test) + { + ZBufCtrl.s3d.zBufEn = GL_TRUE; + ZBufCtrl.s3d.zCmpFunc = zmode & 0x0F; + ZBufCtrl.s3d.zUpdateEn = ctx->Depth.Mask; + + if (imesa->Registers.DrawCtrl.ni.flushPdZbufWrites == GL_FALSE) + { + imesa->Registers.DrawCtrl.ni.flushPdZbufWrites = GL_TRUE; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; +#if 1 + imesa->Registers.ZWatermarks.ni.wLow = 0; + imesa->Registers.changed.ni.fZWatermarksChanged = GL_TRUE; +#endif + } + } + else + { + if (ZBufCtrl.s3d.drawUpdateEn == GL_FALSE) { + ZBufCtrl.s3d.zCmpFunc = LCS_Z_ALWAYS & 0x0F; + ZBufCtrl.s3d.zBufEn = GL_TRUE; + ZBufCtrl.s3d.zUpdateEn = GL_FALSE; + } + else + + /* DRAWUPDATE_REQUIRES_Z_ENABLED*/ + { + ZBufCtrl.s3d.zBufEn = GL_FALSE; + ZBufCtrl.s3d.zUpdateEn = GL_FALSE; + } + + if (imesa->Registers.DrawCtrl.ni.flushPdZbufWrites == GL_TRUE) + { + imesa->Registers.DrawCtrl.ni.flushPdZbufWrites = GL_FALSE; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; + + imesa->Registers.ZWatermarks.ni.wLow = 8; + imesa->Registers.changed.ni.fZWatermarksChanged = GL_TRUE; + } + } + + if (imesa->Registers.ZBufCtrl.ui != ZBufCtrl.ui) + { + imesa->Registers.ZBufCtrl.ui = ZBufCtrl.ui; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + } + + imesa->dirty |= SAVAGE_UPLOAD_CTX; +} + +static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + + imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (flag) + { + if (imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites == GL_FALSE) + { + imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + } + } + else + { + if (imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites == GL_TRUE) + { + imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + } + } + savageDDDepthFunc_s4(ctx,ctx->Depth.Func); +} +static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + + imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (flag) + { + if (imesa->Registers.DrawCtrl.ni.flushPdZbufWrites == GL_FALSE) + { + imesa->Registers.DrawCtrl.ni.flushPdZbufWrites = GL_TRUE; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; + } + } + else + { + if (imesa->Registers.DrawCtrl.ni.flushPdZbufWrites == GL_TRUE) + { + imesa->Registers.DrawCtrl.ni.flushPdZbufWrites = GL_FALSE; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; + } + } + savageDDDepthFunc_s3d(ctx,ctx->Depth.Func); +} + + + + +/* ============================================================= + * Hardware clipping + */ + + + void savageDDScissor( GLcontext *ctx, GLint x, GLint y, + GLsizei w, GLsizei h ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + imesa->scissor_rect.x1 = MAX2(imesa->drawX+x,imesa->draw_rect.x1); + imesa->scissor_rect.y1 = MAX2(imesa->drawY+imesa->driDrawable->h -(y+h), + imesa->draw_rect.y1); + imesa->scissor_rect.x2 = MIN2(imesa->drawX+x+w,imesa->draw_rect.x2); + imesa->scissor_rect.y2 = MIN2(imesa->drawY+imesa->driDrawable->h - y, + imesa->draw_rect.y2); + + + imesa->Registers.changed.ni.fScissorsChanged=GL_TRUE; + + imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS; +} + + + +static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + + /* + * _DrawDestMask is easier to cope with than <mode>. + */ + switch ( ctx->Color._DrawDestMask ) { + case FRONT_LEFT_BIT: + imesa->IsDouble = GL_FALSE; + + if(imesa->IsFullScreen) + { + imesa->drawMap = (char *)imesa->apertureBase[TARGET_FRONT]; + imesa->readMap = (char *)imesa->apertureBase[TARGET_FRONT]; + } + else + { + imesa->drawMap = (char *)imesa->apertureBase[TARGET_BACK]; + imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK]; + } + imesa->NotFirstFrame = GL_FALSE; + imesa->dirty |= SAVAGE_UPLOAD_BUFFERS; + savageXMesaSetFrontClipRects( imesa ); + FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + case BACK_LEFT_BIT: + imesa->IsDouble = GL_TRUE; + imesa->drawMap = (char *)imesa->apertureBase[TARGET_BACK]; + imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK]; + imesa->NotFirstFrame = GL_FALSE; + imesa->dirty |= SAVAGE_UPLOAD_BUFFERS; + savageXMesaSetBackClipRects( imesa ); + FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + default: + FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + + /* We want to update the s/w rast state too so that r200SetBuffer() (?) + * gets called. + */ + _swrast_DrawBuffer(ctx, mode); +} + +static void savageDDReadBuffer(GLcontext *ctx, GLenum mode ) +{ + /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ +} + +#if 0 +static void savageDDSetColor(GLcontext *ctx, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + imesa->MonoColor = savagePackColor( imesa->savageScreen->frontFormat, r, g, b, a ); +} +#endif + +/* ============================================================= + * Window position and viewport transformation + */ + +static void savageCalcViewport( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = imesa->hw_viewport; + + /* See also mga_translate_vertex. + */ + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + imesa->drawX + SUBPIXEL_X; + m[MAT_SY] = - v[MAT_SY]; + m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + imesa->drawY + SUBPIXEL_Y; + m[MAT_SZ] = v[MAT_SZ] * imesa->depth_scale; + m[MAT_TZ] = v[MAT_TZ] * imesa->depth_scale; + + imesa->SetupNewInputs = ~0; +} + +static void savageViewport( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + savageCalcViewport( ctx ); +} + +static void savageDepthRange( GLcontext *ctx, + GLclampd nearval, GLclampd farval ) +{ + savageCalcViewport( ctx ); +} + + +/* ============================================================= + * Miscellaneous + */ + +static void savageDDClearColor(GLcontext *ctx, + const GLfloat color[4] ) +{ + savageContextPtr imesa = SAVAGE_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 = savagePackColor( imesa->savageScreen->frontFormat, + c[0], c[1], c[2], c[3] ); +} + +/* Fallback to swrast for select and feedback. + */ +static void savageRenderMode( GLcontext *ctx, GLenum mode ) +{ + FALLBACK( ctx, SAVAGE_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); +} + + +#if HW_CULL + +/* ============================================================= + * Culling - the savage isn't quite as clean here as the rest of + * its interfaces, but it's not bad. + */ +static void savageDDCullFaceFrontFace(GLcontext *ctx, GLenum unused) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + GLuint cullMode=imesa->LcsCullMode; + switch (ctx->Polygon.CullFaceMode) + { + case GL_FRONT: + switch (ctx->Polygon.FrontFace) + { + case GL_CW: + cullMode = BCM_CW; + break; + case GL_CCW: + cullMode = BCM_CCW; + break; + } + break; + + case GL_BACK: + switch (ctx->Polygon.FrontFace) + { + case GL_CW: + cullMode = BCM_CCW; + break; + case GL_CCW: + cullMode = BCM_CW; + break; + } + break; + } + imesa->LcsCullMode = cullMode; +} +#endif /* end #if HW_CULL */ + +static void savageUpdateCull( GLcontext *ctx ) +{ +#if HW_CULL + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + GLuint cullMode; + if (ctx->Polygon.CullFlag && + imesa->raster_primitive == GL_TRIANGLES && + ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) + cullMode = imesa->LcsCullMode; + else + cullMode = BCM_None; + if (imesa->savageScreen->chipset >= S3_SAVAGE4) { + if (imesa->Registers.DrawCtrl1.ni.cullMode != cullMode) { + imesa->Registers.DrawCtrl1.ni.cullMode = cullMode; + imesa->Registers.changed.ni.fDrawCtrl1Changed = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + } else { + if (imesa->Registers.DrawCtrl.ni.cullMode != cullMode) { + imesa->Registers.DrawCtrl.ni.cullMode = cullMode; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + } +#endif /* end #if HW_CULL */ +} + + + +/* ============================================================= + * Color masks + */ + +/* Mesa calls this from the wrong place - it is called a very large + * number of redundant times. + * + * Colormask can be simulated by multipass or multitexture techniques. + */ +static void savageDDColorMask_s4(GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + GLuint enable; + + if (ctx->Visual.alphaBits) + { + enable = b | g | r | a; + } + else + { + enable = b | g | r; + } + + if (enable) + { + if (imesa->Registers.DrawLocalCtrl.ni.drawUpdateEn == GL_FALSE) + { + imesa->Registers.DrawLocalCtrl.ni.drawUpdateEn = GL_TRUE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + } + else + { + if (imesa->Registers.DrawLocalCtrl.ni.drawUpdateEn) + { + imesa->Registers.DrawLocalCtrl.ni.drawUpdateEn = GL_FALSE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + } + /* TODO: need a software fallback */ +} +static void savageDDColorMask_s3d(GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + GLuint enable; + + if (ctx->Visual.alphaBits) + { + enable = b | g | r | a; + } + else + { + enable = b | g | r; + } + + if (enable) + { + if (imesa->Registers.ZBufCtrl.s3d.drawUpdateEn == GL_FALSE) + { + imesa->Registers.ZBufCtrl.s3d.drawUpdateEn = GL_TRUE; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + } + else + { + if (imesa->Registers.ZBufCtrl.s3d.drawUpdateEn) + { + imesa->Registers.ZBufCtrl.s3d.drawUpdateEn = GL_FALSE; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + } + /* TODO: need a software fallback */ +} + +/* Seperate specular not fully implemented in hardware... Needs + * some interaction with material state? Just punt to software + * in all cases? + * FK: Don't fall back for now. Let's see the failure cases and + * fix them the right way. I don't see how this could be a + * hardware limitation. + */ +static void savageUpdateSpecular_s4(GLcontext *ctx) { + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && + ctx->Light.Enabled) { + if (imesa->Registers.DrawLocalCtrl.ni.specShadeEn == GL_FALSE) { + imesa->Registers.DrawLocalCtrl.ni.specShadeEn = GL_TRUE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + } + /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/ + } else { + if (imesa->Registers.DrawLocalCtrl.ni.specShadeEn == GL_TRUE) { + imesa->Registers.DrawLocalCtrl.ni.specShadeEn = GL_FALSE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + } + /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/ + } +} +static void savageUpdateSpecular_s3d(GLcontext *ctx) { + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && + ctx->Light.Enabled) { + if (imesa->Registers.DrawCtrl.ni.specShadeEn == GL_FALSE) { + imesa->Registers.DrawCtrl.ni.specShadeEn = GL_TRUE; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; + } + FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE); + } else { + if (imesa->Registers.DrawCtrl.ni.specShadeEn == GL_TRUE) { + imesa->Registers.DrawCtrl.ni.specShadeEn = GL_FALSE; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; + } + FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE); + } +} + +static void savageDDLightModelfv_s4(GLcontext *ctx, GLenum pname, + const GLfloat *param) +{ + savageUpdateSpecular_s4 (ctx); +} +static void savageDDLightModelfv_s3d(GLcontext *ctx, GLenum pname, + const GLfloat *param) +{ + savageUpdateSpecular_s3d (ctx); +} + +static void savageDDShadeModel_s4(GLcontext *ctx, GLuint mod) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + + if (mod == GL_SMOOTH) + { + if(imesa->Registers.DrawLocalCtrl.ni.flatShadeEn == GL_TRUE) + { + imesa->Registers.DrawLocalCtrl.ni.flatShadeEn = GL_FALSE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + } + else + { + if(imesa->Registers.DrawLocalCtrl.ni.flatShadeEn == GL_FALSE) + { + imesa->Registers.DrawLocalCtrl.ni.flatShadeEn = GL_TRUE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + } +} +static void savageDDShadeModel_s3d(GLcontext *ctx, GLuint mod) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + + if (mod == GL_SMOOTH) + { + if(imesa->Registers.DrawCtrl.ni.flatShadeEn == GL_TRUE) + { + imesa->Registers.DrawCtrl.ni.flatShadeEn = GL_FALSE; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + } + else + { + if(imesa->Registers.DrawCtrl.ni.flatShadeEn == GL_FALSE) + { + imesa->Registers.DrawCtrl.ni.flatShadeEn = GL_TRUE; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + } +} + + +/* ============================================================= + * Fog + */ + +static void savageDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + GLuint fogClr; + + /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/ + if (ctx->Fog.Enabled) + { + fogClr = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) | + ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) | + ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0)); + if (imesa->Registers.FogCtrl.ni.fogEn != GL_TRUE) + { + imesa->Registers.FogCtrl.ni.fogEn = GL_TRUE; + imesa->Registers.changed.ni.fFogCtrlChanged = GL_TRUE; + } + /*cheap fog*/ + if (imesa->Registers.FogCtrl.ni.fogMode != GL_TRUE) + { + imesa->Registers.FogCtrl.ni.fogMode = GL_TRUE; + imesa->Registers.changed.ni.fFogCtrlChanged = GL_TRUE; + } + if (imesa->Registers.FogCtrl.ni.fogClr != fogClr) + { + imesa->Registers.FogCtrl.ni.fogClr = fogClr; + imesa->Registers.changed.ni.fFogCtrlChanged = GL_TRUE; + } + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + else + { + /*No fog*/ + + if (imesa->Registers.FogCtrl.ni.fogEn != 0) + { + imesa->Registers.FogCtrl.ni.fogEn = 0; + imesa->Registers.FogCtrl.ni.fogMode = 0; + imesa->Registers.changed.ni.fFogCtrlChanged = GL_TRUE; + } + return; + } +} + + +#if HW_STENCIL +static void savageStencilFunc(GLcontext *); + +static void savageDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref, + GLuint mask) +{ + savageStencilFunc(ctx); +} + +static void savageDDStencilMask(GLcontext *ctx, GLuint mask) +{ + savageStencilFunc(ctx); +} + +static void savageDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail, + GLenum zpass) +{ + savageStencilFunc(ctx); +} + +static void savageStencilFunc(GLcontext *ctx) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + Reg_StencilCtrl StencilCtrl; + int a=0; + + StencilCtrl.ui = 0x0; + + if (ctx->Stencil.Enabled) + { + + switch (ctx->Stencil.Function[0]) + { + case GL_NEVER: a = LCS_S_NEVER; break; + case GL_ALWAYS: a = LCS_S_ALWAYS; break; + case GL_LESS: a = LCS_S_LESS; break; + case GL_LEQUAL: a = LCS_S_LEQUAL; break; + case GL_EQUAL: a = LCS_S_EQUAL; break; + case GL_GREATER: a = LCS_S_GREATER; break; + case GL_GEQUAL: a = LCS_S_GEQUAL; break; + case GL_NOTEQUAL: a = LCS_S_NOTEQUAL; break; + default: + break; + } + + StencilCtrl.ni.cmpFunc = (GLuint)a & 0x0F; + StencilCtrl.ni.stencilEn = GL_TRUE; + StencilCtrl.ni.readMask = ctx->Stencil.ValueMask[0]; + StencilCtrl.ni.writeMask = ctx->Stencil.WriteMask[0]; + + switch (ctx->Stencil.FailFunc[0]) + { + case GL_KEEP: + StencilCtrl.ni.failOp = STC_FAIL_Keep; + break; + case GL_ZERO: + StencilCtrl.ni.failOp = STC_FAIL_Zero; + break; + case GL_REPLACE: + StencilCtrl.ni.failOp = STC_FAIL_Equal; + break; + case GL_INCR: + StencilCtrl.ni.failOp = STC_FAIL_IncClamp; + break; + case GL_DECR: + StencilCtrl.ni.failOp = STC_FAIL_DecClamp; + break; + case GL_INVERT: + StencilCtrl.ni.failOp = STC_FAIL_Invert; + break; +#if GL_EXT_stencil_wrap + case GL_INCR_WRAP_EXT: + StencilCtrl.ni.failOp = STC_FAIL_Inc; + break; + case GL_DECR_WRAP_EXT: + StencilCtrl.ni.failOp = STC_FAIL_Dec; + break; +#endif + } + + switch (ctx->Stencil.ZFailFunc[0]) + { + case GL_KEEP: + StencilCtrl.ni.passZfailOp = STC_FAIL_Keep; + break; + case GL_ZERO: + StencilCtrl.ni.passZfailOp = STC_FAIL_Zero; + break; + case GL_REPLACE: + StencilCtrl.ni.passZfailOp = STC_FAIL_Equal; + break; + case GL_INCR: + StencilCtrl.ni.passZfailOp = STC_FAIL_IncClamp; + break; + case GL_DECR: + StencilCtrl.ni.passZfailOp = STC_FAIL_DecClamp; + break; + case GL_INVERT: + StencilCtrl.ni.passZfailOp = STC_FAIL_Invert; + break; +#if GL_EXT_stencil_wrap + case GL_INCR_WRAP_EXT: + StencilCtrl.ni.passZfailOp = STC_FAIL_Inc; + break; + case GL_DECR_WRAP_EXT: + StencilCtrl.ni.passZfailOp = STC_FAIL_Dec; + break; +#endif + } + + switch (ctx->Stencil.ZPassFunc[0]) + { + case GL_KEEP: + StencilCtrl.ni.passZpassOp = STC_FAIL_Keep; + break; + case GL_ZERO: + StencilCtrl.ni.passZpassOp = STC_FAIL_Zero; + break; + case GL_REPLACE: + StencilCtrl.ni.passZpassOp = STC_FAIL_Equal; + break; + case GL_INCR: + StencilCtrl.ni.passZpassOp = STC_FAIL_IncClamp; + break; + case GL_DECR: + StencilCtrl.ni.passZpassOp = STC_FAIL_DecClamp; + break; + case GL_INVERT: + StencilCtrl.ni.passZpassOp = STC_FAIL_Invert; + break; +#if GL_EXT_stencil_wrap + case GL_INCR_WRAP_EXT: + StencilCtrl.ni.passZpassOp = STC_FAIL_Inc; + break; + case GL_DECR_WRAP_EXT: + StencilCtrl.ni.passZpassOp = STC_FAIL_Dec; + break; +#endif + } + + + if (imesa->Registers.StencilCtrl.ui != StencilCtrl.ui) + { + imesa->Registers.StencilCtrl.ui = StencilCtrl.ui; + imesa->Registers.changed.ni.fStencilCtrlChanged = GL_TRUE; + } + + if (imesa->Registers.ZBufCtrl.s4.stencilRefVal != (GLuint) ctx->Stencil.Ref) { + imesa->Registers.ZBufCtrl.s4.stencilRefVal = ctx->Stencil.Ref[0]; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + } + + /* + * force Z on, HW limitation + */ + + if (imesa->Registers.ZBufCtrl.s4.zBufEn != GL_TRUE) + { + imesa->Registers.ZBufCtrl.s4.zCmpFunc = LCS_Z_ALWAYS & 0x0F; + imesa->Registers.ZBufCtrl.s4.zBufEn = GL_TRUE; + imesa->Registers.changed.ni.fZBufCtrlChanged = GL_TRUE; + imesa->Registers.DrawLocalCtrl.ni.zUpdateEn = GL_FALSE; + imesa->Registers.changed.ni.fDrawLocalCtrlChanged = GL_TRUE; + } + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + else + { + if (imesa->Registers.StencilCtrl.ni.stencilEn != GL_FALSE) + { + imesa->Registers.StencilCtrl.ni.stencilEn = GL_FALSE; + imesa->Registers.changed.ni.fStencilCtrlChanged = GL_TRUE; + } + } +} +#endif /* end #if HW_STENCIL */ +/* ============================================================= + */ + +static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state) +{ + + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + unsigned int ui; + switch(cap) { + case GL_ALPHA_TEST: + /* we should consider the disable case*/ + imesa->dirty |= SAVAGE_UPLOAD_CTX; + savageBlendFunc_s4(ctx); + break; + case GL_BLEND: + imesa->dirty |= SAVAGE_UPLOAD_CTX; + /*Can't find Enable bit in the 3D registers.*/ + /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled. + */ + FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); + /*add the savageBlendFunc 2001/11/25 + * if call no such function, then glDisable(GL_BLEND) will do noting, + *our chip has no disable bit + */ + savageBlendFunc_s4(ctx); + break; + case GL_DEPTH_TEST: + imesa->dirty |= SAVAGE_UPLOAD_CTX; + savageDDDepthFunc_s4(ctx,ctx->Depth.Func); + break; + case GL_SCISSOR_TEST: + imesa->scissor = state; + imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS; + break; +#if 0 + case GL_LINE_SMOOTH: + if (ctx->PB->primitive == GL_LINE) { + imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (state) { + ui=imesa->Registers.DrawLocalCtrl.ui; + imesa->Registers.DrawLocalCtrl.ni.flatShadeEn=GL_TRUE; + if(imesa->Registers.DrawLocalCtrl.ui!=ui) + imesa->Registers.changed.ni.fDrawLocalCtrlChanged=GL_TRUE; + } + } + break; + case GL_POINT_SMOOTH: + if (ctx->PB->primitive == GL_POINT) { + imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (state) + { + ui=imesa->Registers.DrawLocalCtrl.ui; + imesa->Registers.DrawLocalCtrl.ni.flatShadeEn=GL_FALSE; + if(imesa->Registers.DrawLocalCtrl.ui!=ui) + imesa->Registers.changed.ni.fDrawLocalCtrlChanged=GL_TRUE; + } + } + break; + case GL_POLYGON_SMOOTH: + if (ctx->PB->primitive == GL_POLYGON) { + imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (state) { + ui=imesa->Registers.DrawLocalCtrl.ui; + imesa->Registers.DrawLocalCtrl.ni.flatShadeEn=GL_TRUE; + if(imesa->Registers.DrawLocalCtrl.ui!=ui) + imesa->Registers.changed.ni.fDrawLocalCtrlChanged=GL_TRUE; + } + } + break; +#endif + case GL_STENCIL_TEST: + imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (state) + { +#if HW_STENCIL + if(imesa->hw_stencil) + { + ui=imesa->Registers.StencilCtrl.ui; +#endif /* end if HW_STENCIL */ + if(!imesa->hw_stencil) + FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, GL_TRUE); + +#if HW_STENCIL + imesa->Registers.StencilCtrl.ni.stencilEn=GL_TRUE; + if(imesa->Registers.StencilCtrl.ui!=ui) + imesa->Registers.changed.ni.fStencilCtrlChanged=GL_TRUE; + } +#endif /* end if HW_STENCIL */ + } + + else + { +#if HW_STENCIL + if(imesa->hw_stencil) + { + if(imesa->Registers.StencilCtrl.ni.stencilEn == GL_TRUE) + { + imesa->Registers.StencilCtrl.ni.stencilEn=GL_FALSE; + imesa->Registers.changed.ni.fStencilCtrlChanged=GL_TRUE; + } + } + FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, GL_FALSE); +#endif + } + break; + case GL_FOG: + imesa->dirty |= SAVAGE_UPLOAD_CTX; + savageDDFogfv(ctx,0,0); + break; + case GL_CULL_FACE: +#if HW_CULL + imesa->dirty |= SAVAGE_UPLOAD_CTX; + ui=imesa->Registers.DrawCtrl1.ui; + if (state) + { + savageDDCullFaceFrontFace(ctx,0); + } + else + { + imesa->Registers.DrawCtrl1.ni.cullMode=BCM_None; + } + if(imesa->Registers.DrawCtrl1.ui!=ui) + imesa->Registers.changed.ni.fDrawCtrl1Changed=GL_TRUE; +#endif + break; + case GL_DITHER: + imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (state) + { + if ( ctx->Color.DitherFlag ) + { + ui=imesa->Registers.DrawCtrl1.ui; + imesa->Registers.DrawCtrl1.ni.ditherEn=GL_TRUE; + if(imesa->Registers.DrawCtrl1.ui!=ui) + imesa->Registers.changed.ni.fDrawCtrl1Changed=GL_TRUE; + } + } + if (!ctx->Color.DitherFlag ) + { + ui=imesa->Registers.DrawCtrl1.ui; + imesa->Registers.DrawCtrl1.ni.ditherEn=GL_FALSE; + if(imesa->Registers.DrawCtrl1.ui!=ui) + imesa->Registers.changed.ni.fDrawCtrl1Changed=GL_TRUE; + } + break; + + case GL_LIGHTING: + savageUpdateSpecular_s4 (ctx); + break; + case GL_TEXTURE_1D: + case GL_TEXTURE_3D: + imesa->new_state |= SAVAGE_NEW_TEXTURE; + break; + case GL_TEXTURE_2D: + imesa->new_state |= SAVAGE_NEW_TEXTURE; + break; + default: + ; + } +} +static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state) +{ + + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + unsigned int ui; + switch(cap) { + case GL_ALPHA_TEST: + /* we should consider the disable case*/ + imesa->dirty |= SAVAGE_UPLOAD_CTX; + savageBlendFunc_s3d(ctx); + break; + case GL_BLEND: + imesa->dirty |= SAVAGE_UPLOAD_CTX; + /*Can't find Enable bit in the 3D registers.*/ + /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled. + */ + FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); + /*add the savageBlendFunc 2001/11/25 + * if call no such function, then glDisable(GL_BLEND) will do noting, + *our chip has no disable bit + */ + savageBlendFunc_s3d(ctx); + break; + case GL_DEPTH_TEST: + imesa->dirty |= SAVAGE_UPLOAD_CTX; + savageDDDepthFunc_s3d(ctx,ctx->Depth.Func); + break; + case GL_SCISSOR_TEST: + imesa->scissor = state; + imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS; + break; + case GL_FOG: + imesa->dirty |= SAVAGE_UPLOAD_CTX; + savageDDFogfv(ctx,0,0); + break; + case GL_CULL_FACE: +#if HW_CULL + imesa->dirty |= SAVAGE_UPLOAD_CTX; + ui=imesa->Registers.DrawCtrl.ui; + if (state) + { + savageDDCullFaceFrontFace(ctx,0); + } + else + { + imesa->Registers.DrawCtrl.ni.cullMode=BCM_None; + } + if(imesa->Registers.DrawCtrl.ui!=ui) + imesa->Registers.changed.ni.fDrawCtrlChanged=GL_TRUE; +#endif + break; + case GL_DITHER: + imesa->dirty |= SAVAGE_UPLOAD_CTX; + if (state) + { + if ( ctx->Color.DitherFlag ) + { + ui=imesa->Registers.DrawCtrl.ui; + imesa->Registers.DrawCtrl.ni.ditherEn=GL_TRUE; + if(imesa->Registers.DrawCtrl.ui!=ui) + imesa->Registers.changed.ni.fDrawCtrlChanged=GL_TRUE; + } + } + if (!ctx->Color.DitherFlag ) + { + ui=imesa->Registers.DrawCtrl.ui; + imesa->Registers.DrawCtrl.ni.ditherEn=GL_FALSE; + if(imesa->Registers.DrawCtrl.ui!=ui) + imesa->Registers.changed.ni.fDrawCtrlChanged=GL_TRUE; + } + break; + + case GL_LIGHTING: + savageUpdateSpecular_s3d (ctx); + break; + case GL_TEXTURE_1D: + case GL_TEXTURE_3D: + imesa->new_state |= SAVAGE_NEW_TEXTURE; + break; + case GL_TEXTURE_2D: + imesa->new_state |= SAVAGE_NEW_TEXTURE; + break; + default: + ; + } +} + +void savageDDUpdateHwState( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + + if(imesa->driDrawable) + { + LOCK_HARDWARE(imesa); + } + + if (imesa->new_state & SAVAGE_NEW_TEXTURE) { + savageUpdateTextureState( ctx ); + } + if((imesa->dirty!=0)|| (imesa->new_state!=0)) + { + savageEmitHwStateLocked(imesa); + imesa->new_state = 0; + } + if(imesa->driDrawable) + { + UNLOCK_HARDWARE(imesa); + } +} + + +void savageEmitDrawingRectangle( savageContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + savageScreenPrivate *savageScreen = imesa->savageScreen; + XF86DRIClipRectPtr pbox; + int nbox; + + + int x0 = imesa->drawX; + int y0 = imesa->drawY; + int x1 = x0 + dPriv->w; + int y1 = y0 + dPriv->h; + + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + + + + /* Coordinate origin of the window - may be offscreen. + */ + /* imesa->BufferSetup[SAVAGE_DESTREG_DR4] = ((y0<<16) | + (((unsigned)x0)&0xFFFF));*/ + + /* Clip to screen. + */ + if (x0 < 0) x0 = 0; + if (y0 < 0) y0 = 0; + if (x1 > savageScreen->width) x1 = savageScreen->width; + if (y1 > savageScreen->height) y1 = savageScreen->height; + + + if(nbox == 1) + { + imesa->draw_rect.x1 = MAX2(x0,pbox->x1); + imesa->draw_rect.y1 = MAX2(y0,pbox->y1); + imesa->draw_rect.x2 = MIN2(x1,pbox->x2); + imesa->draw_rect.y2 = MIN2(y1,pbox->y2); + } + else + { + imesa->draw_rect.x1 = x0; + imesa->draw_rect.y1 = y0; + imesa->draw_rect.x2 = x1; + imesa->draw_rect.y2 = y1; + } + + imesa->Registers.changed.ni.fScissorsChanged=GL_TRUE; + + /* imesa->Registers.changed.ni.fDrawCtrl0Changed=GL_TRUE; + imesa->Registers.changed.ni.fDrawCtrl1Changed=GL_TRUE;*/ + + + imesa->dirty |= SAVAGE_UPLOAD_BUFFERS; +} + + +static void savageDDPrintDirty( const char *msg, GLuint state ) +{ + fprintf(stderr, "%s (0x%x): %s%s%s%s%s\n", + msg, + (unsigned int) state, + (state & SAVAGE_UPLOAD_TEX0IMAGE) ? "upload-tex0, " : "", + (state & SAVAGE_UPLOAD_TEX1IMAGE) ? "upload-tex1, " : "", + (state & SAVAGE_UPLOAD_CTX) ? "upload-ctx, " : "", + (state & SAVAGE_UPLOAD_BUFFERS) ? "upload-bufs, " : "", + (state & SAVAGE_UPLOAD_CLIPRECTS) ? "upload-cliprects, " : "" + ); +} + + + +static void savageUpdateRegister_s4(savageContextPtr imesa) +{ + GLuint *pBCIBase; + pBCIBase = savageDMAAlloc (imesa, 100); + /* + *make sure there is enough room for everything + */ + /*savageKickDMA(imesa);*/ +#define PARAMT 1 +#if defined(PARAMT) && PARAMT +#define GLOBAL_REG SAVAGE_GLOBAL_CHANGED +#else +#define GLOBAL_REG (SAVAGE_GLOBAL_CHANGED | SAVAGE_TEXTURE_CHANGED) +#endif + if (imesa->Registers.changed.uiRegistersChanged & GLOBAL_REG) + { + WRITE_CMD(pBCIBase,WAIT_3D_IDLE,GLuint); + } + + if (imesa->Registers.changed.ni.fTexPalAddrChanged) + { + WRITE_CMD(pBCIBase, SET_REGISTER(SAVAGE_TEXPALADDR_S4, 1),GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexPalAddr.ui,GLuint); + } + + if (imesa->Registers.changed.uiRegistersChanged & 0xFC) + { + WRITE_CMD(pBCIBase, SET_REGISTER(SAVAGE_TEXCTRL0_S4, 6),GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexCtrl[0].ui,GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexCtrl[1].ui,GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexAddr[0].ui,GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexAddr[1].ui,GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexBlendCtrl[0].ui,GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexBlendCtrl[1].ui,GLuint); + } + + if (imesa->Registers.changed.ni.fTexDescrChanged) + { + WRITE_CMD(pBCIBase, SET_REGISTER(SAVAGE_TEXDESCR_S4, 1),GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexDescr.ui,GLuint); + imesa->Registers.TexDescr.s4.newPal = GL_FALSE; + } + + if (imesa->Registers.changed.ni.fFogCtrlChanged) + { + + WRITE_CMD(pBCIBase,SET_REGISTER(SAVAGE_FOGCTRL_S4, 1),GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.FogCtrl.ui,GLuint); + } + + if (imesa->Registers.changed.ni.fDestCtrlChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_DESTCTRL_S4,1),GLuint); + WRITE_CMD( pBCIBase ,imesa->Registers.DestCtrl.ui,GLuint); + } + + if (imesa->Registers.changed.ni.fDrawLocalCtrlChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_DRAWLOCALCTRL_S4,1),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.DrawLocalCtrl.ui,GLuint); + } + /* + * Scissors updates drawctrl0 and drawctrl 1 + */ + + if (imesa->Registers.changed.ni.fScissorsChanged) + { + if(imesa->scissor) + { + imesa->Registers.DrawCtrl0.ni.scissorXStart = imesa->scissor_rect.x1; + imesa->Registers.DrawCtrl0.ni.scissorYStart = imesa->scissor_rect.y1; + imesa->Registers.DrawCtrl1.ni.scissorXEnd = imesa->scissor_rect.x2-1; + imesa->Registers.DrawCtrl1.ni.scissorYEnd = imesa->scissor_rect.y2-1; + } + else + { + imesa->Registers.DrawCtrl0.ni.scissorXStart = imesa->draw_rect.x1; + imesa->Registers.DrawCtrl0.ni.scissorYStart = imesa->draw_rect.y1; + imesa->Registers.DrawCtrl1.ni.scissorXEnd = imesa->draw_rect.x2-1; + imesa->Registers.DrawCtrl1.ni.scissorYEnd = imesa->draw_rect.y2-1; + } + + imesa->Registers.changed.ni.fDrawCtrl0Changed=GL_TRUE; + imesa->Registers.changed.ni.fDrawCtrl1Changed=GL_TRUE; + } + if (imesa->Registers.changed.uiRegistersChanged ) + { + + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_DRAWCTRLGLOBAL0_S4,2),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.DrawCtrl0.ui,GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.DrawCtrl1.ui,GLuint); + + } + + if (imesa->Registers.changed.ni.fZBufCtrlChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_ZBUFCTRL_S4,1),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.ZBufCtrl.ui,GLuint); + } + + if (imesa->Registers.changed.ni.fStencilCtrlChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_STENCILCTRL_S4,1),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.StencilCtrl.ui,GLuint); + } + + if (imesa->Registers.changed.ni.fTexBlendColorChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_TEXBLENDCOLOR_S4,1),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.TexBlendColor.ui,GLuint); + } + + if (imesa->Registers.changed.ni.fZWatermarksChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_ZWATERMARK_S4,1),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.ZWatermarks.ui,GLuint); + } + + if (imesa->Registers.changed.ni.fDestTexWatermarksChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_DESTTEXRWWATERMARK_S4,1),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.DestTexWatermarks.ui,GLuint); + } + + imesa->Registers.changed.uiRegistersChanged = 0; + imesa->dirty=0; + savageDMACommit (imesa, pBCIBase); +} +static void savageUpdateRegister_s3d(savageContextPtr imesa) +{ + GLuint *pBCIBase; + pBCIBase = savageDMAAlloc (imesa, 100); + + /* Always wait for idle for now. + * FIXME: On the Savage3D individual fields in registers can be + * local/global. */ + WRITE_CMD(pBCIBase,WAIT_3D_IDLE,GLuint); + + if (imesa->Registers.changed.ni.fZBufCtrlChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_ZBUFCTRL_S3D,1),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.ZBufCtrl.ui,GLuint); + } + + if (imesa->Registers.changed.ni.fDestCtrlChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_DESTCTRL_S3D,1),GLuint); + WRITE_CMD( pBCIBase ,imesa->Registers.DestCtrl.ui,GLuint); + } + /* Better leave these alone. They don't seem to be needed and I + * don't know exactly what they ary good for. Changing them may + * have been responsible for lockups with texturing. */ +/* + if (imesa->Registers.changed.ni.fZWatermarksChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_ZWATERMARK_S3D,1),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.ZWatermarks.ui,GLuint); + } + if (imesa->Registers.changed.ni.fDestTexWatermarksChanged) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_DESTTEXRWWATERMARK_S3D,1),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.DestTexWatermarks.ui,GLuint); + } +*/ + if (imesa->Registers.changed.ni.fDrawCtrlChanged) + { + /* Same as above. The utah-driver always sets these to true. + * Changing them definitely caused lockups with texturing. */ + imesa->Registers.DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + imesa->Registers.DrawCtrl.ni.flushPdZbufWrites = GL_TRUE; + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_DRAWCTRL_S3D,1),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.DrawCtrl.ui,GLuint); + } + + if (imesa->Registers.changed.ni.fScissorsChanged) + { + if(imesa->scissor) + { + imesa->Registers.ScissorsStart.ni.scissorXStart = + imesa->scissor_rect.x1; + imesa->Registers.ScissorsStart.ni.scissorYStart = + imesa->scissor_rect.y1; + imesa->Registers.ScissorsEnd.ni.scissorXEnd = + imesa->scissor_rect.x2-1; + imesa->Registers.ScissorsEnd.ni.scissorYEnd = + imesa->scissor_rect.y2-1; + } + else + { + imesa->Registers.ScissorsStart.ni.scissorXStart = + imesa->draw_rect.x1; + imesa->Registers.ScissorsStart.ni.scissorYStart = + imesa->draw_rect.y1; + imesa->Registers.ScissorsEnd.ni.scissorXEnd = + imesa->draw_rect.x2-1; + imesa->Registers.ScissorsEnd.ni.scissorYEnd = + imesa->draw_rect.y2-1; + } + + imesa->Registers.changed.ni.fScissorsStartChanged=GL_TRUE; + imesa->Registers.changed.ni.fScissorsEndChanged=GL_TRUE; + } + if (imesa->Registers.changed.uiRegistersChanged & 0x00C00000) + { + WRITE_CMD(pBCIBase , SET_REGISTER(SAVAGE_SCSTART_S3D,2),GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.ScissorsStart.ui,GLuint); + WRITE_CMD(pBCIBase , imesa->Registers.ScissorsEnd.ui,GLuint); + } + + if (imesa->Registers.changed.ni.fTex0CtrlChanged) + { + WRITE_CMD(pBCIBase, SET_REGISTER(SAVAGE_TEXCTRL_S3D, 1),GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexCtrl[0].ui,GLuint); + } + + if (imesa->Registers.changed.ni.fFogCtrlChanged) + { + WRITE_CMD(pBCIBase,SET_REGISTER(SAVAGE_FOGCTRL_S3D, 1),GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.FogCtrl.ui,GLuint); + } + + if (imesa->Registers.changed.ni.fTex0AddrChanged || + imesa->Registers.changed.ni.fTexDescrChanged) + { + WRITE_CMD(pBCIBase, SET_REGISTER(SAVAGE_TEXADDR_S3D, 1),GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexAddr[0].ui,GLuint); + WRITE_CMD(pBCIBase, SET_REGISTER(SAVAGE_TEXDESCR_S3D, 1),GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexDescr.ui,GLuint); + imesa->Registers.TexDescr.s3d.newPal = GL_FALSE; + } + + if (imesa->Registers.changed.ni.fTexPalAddrChanged) + { + WRITE_CMD(pBCIBase, SET_REGISTER(SAVAGE_TEXPALADDR_S3D, 1),GLuint); + WRITE_CMD(pBCIBase, imesa->Registers.TexPalAddr.ui,GLuint); + } + + imesa->Registers.changed.uiRegistersChanged = 0; + imesa->dirty=0; + savageDMACommit (imesa, pBCIBase); +} + + + +/* Push the state into the sarea and/or texture memory. + */ +void savageEmitHwStateLocked( savageContextPtr imesa ) +{ + if (SAVAGE_DEBUG & DEBUG_VERBOSE_API) + savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa->dirty ); + + if (imesa->dirty & ~SAVAGE_UPLOAD_CLIPRECTS) + { + if (imesa->dirty & (SAVAGE_UPLOAD_CTX | SAVAGE_UPLOAD_TEX0 | \ + SAVAGE_UPLOAD_TEX1 | SAVAGE_UPLOAD_BUFFERS)) + { + + SAVAGE_STATE_COPY(imesa); + /* update state to hw*/ + if (imesa->driDrawable &&imesa->driDrawable->numClipRects ==0 ) + { + return ; + } + if (imesa->savageScreen->chipset >= S3_SAVAGE4) + savageUpdateRegister_s4(imesa); + else + savageUpdateRegister_s3d(imesa); + } + + imesa->sarea->dirty |= (imesa->dirty & + ~(SAVAGE_UPLOAD_TEX1|SAVAGE_UPLOAD_TEX0)); + imesa->dirty &= SAVAGE_UPLOAD_CLIPRECTS; + } +} + + + +static void savageDDInitState_s4( savageContextPtr imesa ) +{ +#if 1 + *(GLuint *)&imesa->Registers.DestCtrl = 1<<7; +#else + *(GLuint *)&imesa->Registers.DestCtrl = 0; +#endif + *(GLuint *)&imesa->Registers.ZBufCtrl = 0; + + imesa->Registers.ZBufCtrl.s4.zCmpFunc = LCS_Z_LESS; + imesa->Registers.ZBufCtrl.s4.wToZEn = GL_TRUE; + /*imesa->Registers.ZBufCtrl.ni.floatZEn = GL_TRUE;*/ + *(GLuint *)&imesa->Registers.ZBufOffset = 0; + *(GLuint *)&imesa->Registers.FogCtrl = 0; + imesa->Registers.FogTable.ni.ulEntry[0] = 0; + imesa->Registers.FogTable.ni.ulEntry[1] = 0; + imesa->Registers.FogTable.ni.ulEntry[2] = 0; + imesa->Registers.FogTable.ni.ulEntry[3] = 0; + imesa->Registers.FogTable.ni.ulEntry[4] = 0; + imesa->Registers.FogTable.ni.ulEntry[5] = 0; + imesa->Registers.FogTable.ni.ulEntry[6] = 0; + imesa->Registers.FogTable.ni.ulEntry[7] = 0; + *(GLuint *)&imesa->Registers.TexDescr = 0; + imesa->Registers.TexAddr[0].ui = 0; + imesa->Registers.TexAddr[1].ui = 0; + imesa->Registers.TexPalAddr.ui = 0; + *(GLuint *)&imesa->Registers.TexCtrl[0] = 0; + *(GLuint *)&imesa->Registers.TexCtrl[1] = 0; + imesa->Registers.TexBlendCtrl[0].ui = TBC_NoTexMap; + imesa->Registers.TexBlendCtrl[1].ui = TBC_NoTexMap1; + *(GLuint *)&imesa->Registers.DrawCtrl0 = 0; +#if 1/*def __GL_HALF_PIXEL_OFFSET*/ + *(GLuint *)&imesa->Registers.DrawCtrl1 = 0; +#else + *(GLuint *)&imesa->Registers.DrawCtrl1 = 1<<11; +#endif + *(GLuint *)&imesa->Registers.DrawLocalCtrl = 0; + *(GLuint *)&imesa->Registers.StencilCtrl = 0; + + /* Set DestTexWatermarks_31,30 to 01 always. + *Has no effect if dest. flush is disabled. + */ +#if 0 + *(GLuint *)&imesa->Registers.ZWatermarks = 0x12000C04; + *(GLuint *)&imesa->Registers.DestTexWatermarks = 0x40200400; +#else + *(GLuint *)&imesa->Registers.ZWatermarks = 0x16001808; + *(GLuint *)&imesa->Registers.DestTexWatermarks = 0x4f000000; +#endif + imesa->Registers.DrawCtrl0.ni.DPerfAccelEn = GL_TRUE; + + /* clrCmpAlphaBlendCtrl is needed to get alphatest and + * alpha blending working properly + */ + + imesa->Registers.TexCtrl[0].s4.dBias = 0x08; + imesa->Registers.TexCtrl[1].s4.dBias = 0x08; + imesa->Registers.TexCtrl[0].s4.texXprEn = GL_TRUE; + imesa->Registers.TexCtrl[1].s4.texXprEn = GL_TRUE; + imesa->Registers.TexCtrl[0].s4.dMax = 0x0f; + imesa->Registers.TexCtrl[1].s4.dMax = 0x0f; + imesa->Registers.DrawLocalCtrl.ni.drawUpdateEn = GL_TRUE; + imesa->Registers.DrawLocalCtrl.ni.srcAlphaMode = SAM_One; + imesa->Registers.DrawLocalCtrl.ni.wrZafterAlphaTst = GL_FALSE; + imesa->Registers.DrawLocalCtrl.ni.flushPdZbufWrites= GL_TRUE; + imesa->Registers.DrawLocalCtrl.ni.flushPdDestWrites= GL_TRUE; + + imesa->Registers.DrawLocalCtrl.ni.zUpdateEn= GL_TRUE; + imesa->Registers.DrawCtrl1.ni.ditherEn=GL_TRUE; + imesa->Registers.DrawCtrl1.ni.cullMode = BCM_None; + + imesa->LcsCullMode=BCM_None; + imesa->Registers.TexDescr.s4.palSize = TPS_256; +} +static void savageDDInitState_s3d( savageContextPtr imesa ) +{ +#if 1 + imesa->Registers.DestCtrl.ui = 1<<7; +#else + imesa->Registers.DestCtrl.ui = 0; +#endif + imesa->Registers.ZBufCtrl.ui = 0; + + imesa->Registers.ZBufCtrl.s3d.zCmpFunc = LCS_Z_LESS & 0x07; + imesa->Registers.ZBufOffset.ui = 0; + imesa->Registers.FogCtrl.ui = 0; + memset (imesa->Registers.FogTable.ni.ucEntry, 0, 64); + imesa->Registers.TexDescr.ui = 0; + imesa->Registers.TexAddr[0].ui = 0; + imesa->Registers.TexPalAddr.ui = 0; + imesa->Registers.TexCtrl[0].ui = 0; +#if 1/*def __GL_HALF_PIXEL_OFFSET*/ + imesa->Registers.DrawCtrl.ui = 0; +#else + imesa->Registers.DrawCtrl.ui = 1<<1; +#endif + imesa->Registers.ScissorsStart.ui = 0; + imesa->Registers.ScissorsEnd.ui = 0; + + /* Set DestTexWatermarks_31,30 to 01 always. + *Has no effect if dest. flush is disabled. + */ +#if 0 + imesa->Registers.ZWatermarks.ui = 0x12000C04; + imesa->Registers.DestTexWatermarks.ui = 0x40200400; +#else + imesa->Registers.ZWatermarks.ui = 0x16001808; + imesa->Registers.DestTexWatermarks.ui = 0x4f000000; +#endif + + /* clrCmpAlphaBlendCtrl is needed to get alphatest and + * alpha blending working properly + */ + + imesa->Registers.TexCtrl[0].s3d.dBias = 0x08; + imesa->Registers.TexCtrl[0].s3d.texXprEn = GL_TRUE; + + imesa->Registers.ZBufCtrl.s3d.drawUpdateEn = GL_TRUE; + imesa->Registers.ZBufCtrl.s3d.wrZafterAlphaTst = GL_FALSE; + imesa->Registers.ZBufCtrl.s3d.zUpdateEn = GL_TRUE; + + imesa->Registers.DrawCtrl.ni.srcAlphaMode = SAM_One; + imesa->Registers.DrawCtrl.ni.flushPdZbufWrites = GL_TRUE; + imesa->Registers.DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + + imesa->Registers.DrawCtrl.ni.ditherEn = GL_TRUE; + imesa->Registers.DrawCtrl.ni.cullMode = BCM_None; + + imesa->LcsCullMode = BCM_None; + imesa->Registers.TexDescr.s3d.palSize = TPS_256; +} +void savageDDInitState( savageContextPtr imesa ) { + volatile GLuint* pBCIBase; + if (imesa->savageScreen->chipset >= S3_SAVAGE4) + savageDDInitState_s4 (imesa); + else + savageDDInitState_s3d (imesa); + + /*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/ + imesa->Registers.DestCtrl.ni.offset = imesa->savageScreen->backOffset>>11; + if(imesa->savageScreen->cpp == 2) + { + imesa->Registers.DestCtrl.ni.dstPixFmt = 0; + imesa->Registers.DestCtrl.ni.dstWidthInTile = + (imesa->savageScreen->width+63)>>6; + } + else + { + imesa->Registers.DestCtrl.ni.dstPixFmt = 1; + imesa->Registers.DestCtrl.ni.dstWidthInTile = + (imesa->savageScreen->width+31)>>5; + } + + imesa->IsDouble = GL_TRUE; + + imesa->NotFirstFrame = GL_FALSE; + imesa->Registers.ZBufOffset.ni.offset=imesa->savageScreen->depthOffset>>11; + if(imesa->savageScreen->zpp == 2) + { + imesa->Registers.ZBufOffset.ni.zBufWidthInTiles = + (imesa->savageScreen->width+63)>>6; + imesa->Registers.ZBufOffset.ni.zDepthSelect = 0; + } + else + { + imesa->Registers.ZBufOffset.ni.zBufWidthInTiles = + (imesa->savageScreen->width+31)>>5; + imesa->Registers.ZBufOffset.ni.zDepthSelect = 1; + } + + if (imesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT) { + if(imesa->IsFullScreen) + { + imesa->toggle = TARGET_BACK; + + imesa->drawMap = (char *)imesa->apertureBase[imesa->toggle]; + imesa->readMap = (char *)imesa->apertureBase[imesa->toggle]; + } + else + { + imesa->drawMap = (char *)imesa->apertureBase[TARGET_BACK]; + imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK]; + } + + } else { + + if(imesa->IsFullScreen) + { + imesa->toggle = TARGET_BACK; + + imesa->drawMap = (char *)imesa->apertureBase[imesa->toggle]; + imesa->readMap = (char *)imesa->apertureBase[imesa->toggle]; + } + else + { + imesa->drawMap = (char *)imesa->apertureBase[TARGET_BACK]; + imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK]; + } + } + +#if 0 + if(imesa->driDrawable) + { + LOCK_HARDWARE(imesa); + } + pBCIBase=SAVAGE_GET_BCI_POINTER(imesa,38); + *pBCIBase++ = WAIT_3D_IDLE; + pBCIBase[0] = SET_REGISTER(DST,1); + pBCIBase[1] = imesa->Registers.DestCtrl.ui; + pBCIBase+=2; + + pBCIBase[0] = SET_REGISTER(ZBUFCTRL,1); + pBCIBase[1] = imesa->Registers.ZBufCtrl.ui; + pBCIBase+=2; + + pBCIBase[0] = SET_REGISTER(ZBUFOFF,1); + pBCIBase[1] = imesa->Registers.ZBufOffset.ui; + pBCIBase+=2; + + pBCIBase[0] = SET_REGISTER(FOGCTRL,1); + pBCIBase[1] = imesa->Registers.FogCtrl.ui; + pBCIBase+=2; + + + pBCIBase[0] = SET_REGISTER(FOGTABLE,8); + memcpy((GLvoid *)(pBCIBase+1),(GLvoid *)imesa->Registers.FogTable.ni.ulEntry,32); + pBCIBase+=9; + + pBCIBase[0] = SET_REGISTER(DRAWLOCALCTRL,1); + pBCIBase[1] = imesa->Registers.DrawLocalCtrl.ui; + pBCIBase+=2; + + pBCIBase[0] = SET_REGISTER(DRAWCTRLGLOBAL0,2); + pBCIBase[1] = imesa->Registers.DrawCtrl0.ui; + pBCIBase[2] = imesa->Registers.DrawCtrl1.ui; + pBCIBase+=3; + + + pBCIBase[0] = SET_REGISTER(TEXPALADDR,1); + pBCIBase[1] = imesa->Registers.TexPalAddr.ui; + pBCIBase+=2; + + + pBCIBase[0] = SET_REGISTER(TEXCTRL0,6); + pBCIBase[1] = imesa->Registers.TexCtrl[0].ui; + pBCIBase[2] = imesa->Registers.TexCtrl[1].ui; + + pBCIBase[3] = imesa->Registers.TexAddr[0].ui; + pBCIBase[4] = imesa->Registers.TexAddr[1].ui; + pBCIBase[5] = imesa->Registers.TexBlendCtrl[0].ui; + pBCIBase[6] = imesa->Registers.TexBlendCtrl[1].ui; + pBCIBase+=7; + + pBCIBase[0] = SET_REGISTER(TEXDESCR,1); + pBCIBase[1] = imesa->Registers.TexDescr.ui; + pBCIBase+=2; + + + pBCIBase[0] = SET_REGISTER(STENCILCTRL,1); + pBCIBase[1] = imesa->Registers.StencilCtrl.ui; + pBCIBase+=2; + + pBCIBase[0] = SET_REGISTER(ZWATERMARK,1); + pBCIBase[1] = imesa->Registers.ZWatermarks.ui; + pBCIBase+=2; + + pBCIBase[0] = SET_REGISTER(DESTTEXRWWATERMARK,1); + pBCIBase[1] = imesa->Registers.DestTexWatermarks.ui; + pBCIBase+=2; + + if(imesa->driDrawable) + { + UNLOCK_HARDWARE(imesa); + } +#else + if(imesa->driDrawable) + LOCK_HARDWARE(imesa); + + /* This is the only reg that is not emitted in savageUpdateRegisters. + * FIXME: Should this be set by the Xserver? */ + pBCIBase = SAVAGE_GET_BCI_POINTER(imesa,3); + *pBCIBase++ = WAIT_3D_IDLE; + *pBCIBase++ = SET_REGISTER(SAVAGE_ZBUFOFF_S4,1); /* The same on S3D. */ + *pBCIBase++ = imesa->Registers.ZBufOffset.ui; + + if(imesa->driDrawable) + UNLOCK_HARDWARE(imesa); + imesa->Registers.changed.uiRegistersChanged = ~0; +#endif +} + + +#define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\ + NEW_TEXTURE_MATRIX|\ + NEW_USER_CLIP|NEW_CLIENT_STATE)) + +void savageDDRenderStart(GLcontext *ctx) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + XF86DRIClipRectPtr pbox; + GLint nbox; + + /* if the screen is overrided by other application. set the scissor. + * In MulitPass, re-render the screen. + */ + pbox = dPriv->pClipRects; + nbox = dPriv->numClipRects; + if (nbox) + { + imesa->currentClip = nbox; + /* set scissor to the first clip box*/ + savageDDScissor(ctx,pbox->x1,pbox->y1,pbox->x2,pbox->y2); + + savageUpdateCull(ctx); + savageDDUpdateHwState(ctx); /* update to hardware register*/ + } + else /* need not render at all*/ + { + /*ctx->VB->CopyStart = ctx->VB->Count;*/ + } + LOCK_HARDWARE(SAVAGE_CONTEXT(ctx)); +} + + +void savageDDRenderEnd(GLcontext *ctx) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + + UNLOCK_HARDWARE(SAVAGE_CONTEXT(ctx)); + if(!imesa->IsDouble) + { + savageSwapBuffers(imesa->driDrawable); + } + +} + +static void savageDDInvalidateState( 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 ); + SAVAGE_CONTEXT(ctx)->new_gl_state |= new_state; +} + + +void savageDDInitStateFuncs(GLcontext *ctx) +{ + ctx->Driver.UpdateState = savageDDInvalidateState; + ctx->Driver.BlendEquationSeparate = savageDDBlendEquationSeparate; + ctx->Driver.Fogfv = savageDDFogfv; + ctx->Driver.Scissor = savageDDScissor; +#if HW_CULL + ctx->Driver.CullFace = savageDDCullFaceFrontFace; + ctx->Driver.FrontFace = savageDDCullFaceFrontFace; +#else + ctx->Driver.CullFace = 0; + ctx->Driver.FrontFace = 0; +#endif /* end #if HW_CULL */ + ctx->Driver.PolygonMode=NULL; + ctx->Driver.PolygonStipple = 0; + ctx->Driver.LineStipple = 0; + ctx->Driver.LineWidth = 0; + ctx->Driver.LogicOpcode = 0; + ctx->Driver.DrawBuffer = savageDDDrawBuffer; + ctx->Driver.ReadBuffer = savageDDReadBuffer; + ctx->Driver.ClearColor = savageDDClearColor; + + ctx->Driver.DepthRange = savageDepthRange; + ctx->Driver.Viewport = savageViewport; + ctx->Driver.RenderMode = savageRenderMode; + + ctx->Driver.ClearIndex = 0; + ctx->Driver.IndexMask = 0; + + if (SAVAGE_CONTEXT( ctx )->savageScreen->chipset >= S3_SAVAGE4) { + ctx->Driver.Enable = savageDDEnable_s4; + ctx->Driver.AlphaFunc = savageDDAlphaFunc_s4; + ctx->Driver.DepthFunc = savageDDDepthFunc_s4; + ctx->Driver.DepthMask = savageDDDepthMask_s4; + ctx->Driver.BlendFuncSeparate = savageDDBlendFuncSeparate_s4; + ctx->Driver.ColorMask = savageDDColorMask_s4; + ctx->Driver.ShadeModel = savageDDShadeModel_s4; + ctx->Driver.LightModelfv = savageDDLightModelfv_s4; +#if HW_STENCIL + ctx->Driver.StencilFunc = savageDDStencilFunc; + ctx->Driver.StencilMask = savageDDStencilMask; + ctx->Driver.StencilOp = savageDDStencilOp; +#else + ctx->Driver.StencilFunc = 0; + ctx->Driver.StencilMask = 0; + ctx->Driver.StencilOp = 0; +#endif /* end #if HW_STENCIL */ + } else { + ctx->Driver.Enable = savageDDEnable_s3d; + ctx->Driver.AlphaFunc = savageDDAlphaFunc_s3d; + ctx->Driver.DepthFunc = savageDDDepthFunc_s3d; + ctx->Driver.DepthMask = savageDDDepthMask_s3d; + ctx->Driver.BlendFuncSeparate = savageDDBlendFuncSeparate_s3d; + ctx->Driver.ColorMask = savageDDColorMask_s3d; + ctx->Driver.ShadeModel = savageDDShadeModel_s3d; + ctx->Driver.LightModelfv = savageDDLightModelfv_s3d; + ctx->Driver.StencilFunc = 0; + ctx->Driver.StencilMask = 0; + ctx->Driver.StencilOp = 0; + } + + /* 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/savage/savagestate.h b/src/mesa/drivers/dri/savage/savagestate.h new file mode 100644 index 0000000000..cc3038904d --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagestate.h @@ -0,0 +1,69 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#ifndef _SAVAGE_STATE_H +#define _SAVAGE_STATE_H + +#include "savagecontext.h" + +extern void savageDDUpdateHwState( GLcontext *ctx ); +extern void savageDDInitState( savageContextPtr imesa ); +extern void savageDDInitStateFuncs( GLcontext *ctx ); +extern void savageDDRenderStart(GLcontext *ctx); +extern void savageDDRenderEnd(GLcontext *ctx); +extern void savageDDScissor( GLcontext *ctx, GLint x, GLint y,GLsizei w, GLsizei h ); + +/*frank 2001/11/13 add macro for sarea state copy*/ +#define SAVAGE_STATE_COPY(ctx) { \ +ctx->sarea->setup[0]=ctx->Registers.DrawLocalCtrl.ui; \ +ctx->sarea->setup[1]=ctx->Registers.TexPalAddr.ui; \ +ctx->sarea->setup[2]=ctx->Registers.TexCtrl[0].ui; \ +ctx->sarea->setup[3]=ctx->Registers.TexCtrl[1].ui; \ +ctx->sarea->setup[4]=ctx->Registers.TexAddr[0].ui; \ +ctx->sarea->setup[5]=ctx->Registers.TexAddr[1].ui; \ +ctx->sarea->setup[6]=ctx->Registers.TexBlendCtrl[0].ui; \ +ctx->sarea->setup[7]=ctx->Registers.TexBlendCtrl[1].ui; \ +ctx->sarea->setup[8]=ctx->Registers.TexXprClr.ui; \ +ctx->sarea->setup[9]=ctx->Registers.TexDescr.ui; \ +ctx->sarea->setup[10]=ctx->Registers.FogTable.ni.ulEntry[0]; \ +ctx->sarea->setup[11]=ctx->Registers.FogTable.ni.ulEntry[1]; \ +ctx->sarea->setup[12]=ctx->Registers.FogTable.ni.ulEntry[2]; \ +ctx->sarea->setup[13]=ctx->Registers.FogTable.ni.ulEntry[3]; \ +ctx->sarea->setup[14]=ctx->Registers.FogTable.ni.ulEntry[4]; \ +ctx->sarea->setup[15]=ctx->Registers.FogTable.ni.ulEntry[5]; \ +ctx->sarea->setup[16]=ctx->Registers.FogTable.ni.ulEntry[6]; \ +ctx->sarea->setup[17]=ctx->Registers.FogTable.ni.ulEntry[7]; \ +ctx->sarea->setup[18]=ctx->Registers.FogCtrl.ui; \ +ctx->sarea->setup[19]=ctx->Registers.StencilCtrl.ui; \ +ctx->sarea->setup[20]=ctx->Registers.ZBufCtrl.ui; \ +ctx->sarea->setup[21]=ctx->Registers.ZBufOffset.ui; \ +ctx->sarea->setup[22]=ctx->Registers.DestCtrl.ui; \ +ctx->sarea->setup[23]=ctx->Registers.DrawCtrl0.ui; \ +ctx->sarea->setup[24]=ctx->Registers.DrawCtrl1.ui; \ +ctx->sarea->setup[25]=ctx->Registers.ZWatermarks.ui; \ +ctx->sarea->setup[26]=ctx->Registers.DestTexWatermarks.ui; \ +ctx->sarea->setup[27]=ctx->Registers.TexBlendColor.ui; \ +} +#endif diff --git a/src/mesa/drivers/dri/savage/savagetex.c b/src/mesa/drivers/dri/savage/savagetex.c new file mode 100644 index 0000000000..94a4b23aec --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagetex.c @@ -0,0 +1,2022 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#include <stdlib.h> +#include <stdio.h> + +#include <GL/gl.h> + +#include "mm.h" +#include "savagecontext.h" +#include "savagetex.h" +#include "savagetris.h" +#include "savageioctl.h" +#include "simple_list.h" +#include "enums.h" +#include "savage_bci.h" + +#include "macros.h" +#include "texformat.h" +#include "texstore.h" +#include "texobj.h" + +#include "swrast/swrast.h" + +/* declarations of static and inline functions */ +__inline GLuint GetTiledCoordinates8(GLuint iBufferWidth, GLint x, GLint y); +static GLuint GetTiledCoordinates16_4( GLint iBufferWidth,GLint x,GLint y ); +static GLuint GetTiledCoordinates16_8( GLint iBufferWidth,GLint x,GLint y ); +static GLuint GetTiledCoordinates32_4( GLint iBufferWidth, GLint x, GLint y ); +static GLuint GetTiledCoordinates32_8( GLint iBufferWidth, GLint x, GLint y ); +__inline GLuint GetTiledCoordinates( GLint iDepth,GLint iBufferWidth,GLint x,GLint y ); +__inline void savageUploadImage(savageTextureObjectPtr t, GLuint level, GLuint startx, GLuint starty, GLuint reloc); +__inline void savageTileTex(savageTextureObjectPtr tex, GLuint level); + +/* tile sizes depending on texel color depth */ +GLuint gTileWidth[5] = +{ + 64, /* 4-bit */ + 64, /* 8-bit */ + 64, /* 16-bit */ + 0, /* 24-bit */ + 32 /* 32-bit */ +}; + +GLuint gTileHeight[5] = +{ + 64, /* 4-bit */ + 32, /* 8-bit */ + 16, /* 16-bit */ + 0, /* 24-bit */ + 16 /* 32-bit */ +}; + +__inline GLuint GetTiledCoordinates8(GLuint iBufferWidth, GLint x, GLint y) +{ + GLint x10, x106, x52; + GLint y20, y105, y43; + GLuint uWidthInTiles; + + uWidthInTiles = (iBufferWidth + 63) >> 6; + x10 = x & 0x3; + x52 = (x & 0x3c) >> 2; + x106 = (x & 0x7c0) >> 6; + + y20 = y & 0x7; + y43 = (y & 0x18) >> 3; + y105 = (y & 0x7e0) >> 5; + + return ( x10 | + (y20 << 2) | + (x52 << 5) | + (y43 << 9) | + ((y105 * uWidthInTiles) + x106) << 11 ); +} + +/* 4-pixel wide subtiles */ +static GLuint GetTiledCoordinates16_4( GLint iBufferWidth, + GLint x, + GLint y ) +{ + GLint x106; + GLint x10; + GLint x52; + GLint y104; + GLint y20; + GLint y3; + GLuint uiWidthInTiles; + + /* + // calculating tiled address + */ + + uiWidthInTiles = (iBufferWidth + 63) >> 6; + + x10 = x & 0x3; + x52 = (x & 0x3c ) >> 2; + x106 = (x & 0x7c0) >> 6; + + y20 = y & 0x7; + y3 = (y & 8 ) >> 3; + y104 = (y & 0x7f0) >> 4; + + return( (x10 << 1) | + (y20 << 3) | + (x52 << 6) | + (y3 << 10) | + ((y104 * uiWidthInTiles) + x106) << 11 ); +} +/* 8-pixel wide subtiles */ +static GLuint GetTiledCoordinates16_8( GLint iBufferWidth, + GLint x, + GLint y ) +{ + GLint x106; + GLint x20; + GLint x53; + GLint y104; + GLint y20; + GLint y3; + GLuint uiWidthInTiles; + + /* + // calculating tiled address + */ + + uiWidthInTiles = (iBufferWidth + 63) >> 6; + + x20 = x & 0x7; + x53 = (x & 0x38 ) >> 3; + x106 = (x & 0x7c0) >> 6; + + y20 = y & 0x7; + y3 = (y & 8 ) >> 3; + y104 = (y & 0x7f0) >> 4; + + return( (x20 << 1) | + (y20 << 4) | + (x53 << 7) | + (y3 << 10) | + ((y104 * uiWidthInTiles) + x106) << 11 ); +} +/* function pointer set to the correct version in savageDDInitTextureFuncs */ +GLuint (*GetTiledCoordinates16) (GLint, GLint, GLint); + +/* 4-pixel wide subtiles */ +static GLuint GetTiledCoordinates32_4( GLint iBufferWidth, + GLint x, + GLint y ) +{ + GLint x10; + GLint y20; + GLuint uiWidthInTiles; + GLint x42; + GLint x105; + GLint y3; + GLint y104; + + /* + // calculating tiled address + */ + + uiWidthInTiles = (iBufferWidth + 31) >> 5; + + x10 = x & 0x3; + x42 = (x & 0x1c ) >> 2; + x105 = (x & 0x7e0) >> 5; + + y20 = y & 0x7; + y3 = (y & 8 ) >> 3; + y104 = (y & 0x7f0) >> 4; + + return( (x10 << 2) | + (y20 << 4) | + (x42 << 7) | + (y3 << 10) | + ((y104 * uiWidthInTiles) + x105) << 11 ); +} +/* 8-pixel wide subtiles */ +static GLuint GetTiledCoordinates32_8( GLint iBufferWidth, + GLint x, + GLint y ) +{ + GLint x20; + GLint y20; + GLuint uiWidthInTiles; + GLint x43; + GLint x105; + GLint y3; + GLint y104; + + /* + // calculating tiled address + */ + + uiWidthInTiles = (iBufferWidth + 31) >> 5; + + x20 = x & 0x7; + x43 = (x & 0x18 ) >> 3; + x105 = (x & 0x7e0) >> 5; + + y20 = y & 0x7; + y3 = (y & 8 ) >> 3; + y104 = (y & 0x7f0) >> 4; + + return( (x20 << 2) | + (y20 << 5) | + (x43 << 8) | + (y3 << 10) | + ((y104 * uiWidthInTiles) + x105) << 11 ); +} +/* function pointer set to the correct version in savageDDInitTextureFuncs */ +GLuint (*GetTiledCoordinates32) (GLint, GLint, GLint); + +__inline GLuint GetTiledCoordinates( GLint iDepth, + GLint iBufferWidth, + GLint x, + GLint y ) +{ + /* + // don't check for 4 since we only have 3 types of fb + */ + + if (iDepth == 16) + { + return( GetTiledCoordinates16( iBufferWidth, x, y ) ); + } + else if (iDepth == 32) + { + return( GetTiledCoordinates32( iBufferWidth, x, y ) ); + } + else + { + return( GetTiledCoordinates8( iBufferWidth, x, y ) ); + } +} + +__inline void savageUploadImage(savageTextureObjectPtr t, GLuint level, GLuint startx, GLuint starty, GLuint reloc) +{ + GLuint uMaxTileWidth = gTileWidth[t->texelBytes]; + GLuint x, y, w, row, col; + const struct gl_texture_image *image = t->image[level].image; + GLubyte * dst, * src, * pBuffer; + GLint xAdd, yAdd; + GLuint uRowSeparator, uChunk = MIN_TILE_CHUNK, uWrap; + + + pBuffer = (GLubyte *)(t->BufAddr + t->image[level].offset); + src = (GLubyte *)image->Data; + x = startx; + y = starty; + w = image->Width; + + if(image->Format == GL_COLOR_INDEX) + { + if(w < MIN_TILE_CHUNK) + { + w = MIN_TILE_CHUNK; + } + else + { + if((w > 64 ) && (image->Height <= 16)) + { + reloc = GL_TRUE; + if(image->Height == 16) + { + uChunk = MIN_TILE_CHUNK << 1; + } + } + } + + if(!reloc & (w > (64 / 2))) + { + for(row = 0; row < image->Height; row++) + { + for(col = 0; col < image->Width; col++) + { + dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, w, x + col, y + row); + memcpy (dst, src, t->texelBytes); + src += t->texelBytes; + } + } + } + else + { + if(reloc & (w > 64)) + { + uWrap = ((w + 63) >> 6) - 1; + for(row = 0; row < image->Height; row++) + { + for(col = 0; col < image->Width; col++) + { + xAdd = (col / (4 * 64)) * 64 + col % 64; + yAdd = row + ((col / 64) & 3) * uChunk; + dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, 64, x + xAdd, y + yAdd); + memcpy (dst, src, t->texelBytes); + src += t->texelBytes; + } + } + } + else + { + uRowSeparator = 64 * MIN_TILE_CHUNK / w; + for(row = 0; row < image->Height; row++) + { + xAdd = (w * (row / MIN_TILE_CHUNK)) % 64; + yAdd = row % MIN_TILE_CHUNK + MIN_TILE_CHUNK * (row / uRowSeparator); + for(col = 0; col < image->Width; col++) + { + dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, w, x + xAdd, y + yAdd); + memcpy (dst, src, t->texelBytes); + src += t->texelBytes; + } + } + } + } + } + else + { + if(w < MIN_TILE_CHUNK) + { + w = MIN_TILE_CHUNK; + } + else + { + if((w > uMaxTileWidth ) && (image->Height <= 8)) + { + reloc = GL_TRUE; + } + } + if(!reloc & (w > uMaxTileWidth / 2)) + { + for(row = 0; row < image->Height; row++) + { + for(col = 0; col < image->Width; col++) + { + dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, w, x + col, y + row); + memcpy (dst, src, t->texelBytes); + src += t->texelBytes; + } + } + } + else + { + if(reloc & (w > uMaxTileWidth)) + { + for(row = 0; row < image->Height; row++) + { + for(col = 0; col < image->Width; col++) + { + xAdd = (col / (2 * uMaxTileWidth)) * uMaxTileWidth + col % uMaxTileWidth; + yAdd = row + ((col / uMaxTileWidth) & 1) * MIN_TILE_CHUNK; + dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, w, x + xAdd, y + yAdd); + memcpy (dst, src, t->texelBytes); + src += t->texelBytes; + } + } + } + else + { + uRowSeparator = uMaxTileWidth * MIN_TILE_CHUNK / w; + for(row = 0; row < image->Height; row++) + { + yAdd = row % MIN_TILE_CHUNK + MIN_TILE_CHUNK * (row / uRowSeparator); + xAdd = (w * (row / MIN_TILE_CHUNK)) % uMaxTileWidth; + for(col = 0; col < image->Width; col++) + { + dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, w, x + col + xAdd, y + yAdd); + memcpy (dst, src, t->texelBytes); + src += t->texelBytes; + } + } + } + } + } +} + + + +__inline void savageTileTex(savageTextureObjectPtr tex, GLuint level) +{ + GLuint uWidth, uHeight; + GLint xOffset, yOffset; + GLint xStart=0, yStart=0; + GLint minSize; + GLuint xRepeat, yRepeat; + GLuint startCol, startRow; + GLuint reloc; + + const struct gl_texture_image *image = tex->image[level].image; + + reloc = GL_FALSE; + uWidth = image->Width2; + uHeight = image->Height2; + + if((uWidth > 4) || (uHeight > 4)) + minSize = MIN_TILE_CHUNK; + else + minSize = MIPMAP_CHUNK; + + if(image->Width >= minSize) + xRepeat = 1; + else + xRepeat = minSize / image->Width; + + if(image->Height >= minSize) + yRepeat = 1; + else + { + yRepeat = minSize / image->Height; + if(minSize == MIN_TILE_CHUNK) + reloc = GL_TRUE; + } + + if(((uWidth < 4) && (uHeight < 4)) && (tex->texelBytes >= 2)) + { + if((uWidth == 2) || (uHeight == 2)) + { + xStart = 4; + yStart = 0; + } + + else + { + xStart = 4; + yStart = 4; + } + } + for(xOffset = 0; xOffset < xRepeat; xOffset++) + { + for(yOffset = 0; yOffset < yRepeat; yOffset++) + { + startCol = image->Width * xOffset + xStart; + startRow = image->Height * yOffset + yStart; + savageUploadImage(tex,level, startCol, startRow, reloc); + } + } +} + +static void savageSetTexWrapping(savageTextureObjectPtr tex, GLenum s, GLenum t) +{ + tex->texParams.sWrapMode = s; + tex->texParams.tWrapMode = t; +} + +static void savageSetTexFilter(savageTextureObjectPtr t, + GLenum minf, GLenum magf) +{ + t->texParams.minFilter = minf; + t->texParams.magFilter = magf; +} + + +/* Need a fallback ? + */ +static void savageSetTexBorderColor(savageTextureObjectPtr t, GLubyte color[4]) +{ +/* t->Setup[SAVAGE_TEXREG_TEXBORDERCOL] = */ + t->texParams.boarderColor = SAVAGEPACKCOLOR8888(color[0],color[1],color[2],color[3]); +} + + + +static savageTextureObjectPtr +savageAllocTexObj( struct gl_texture_object *texObj ) +{ + savageTextureObjectPtr t; + + t = (savageTextureObjectPtr) calloc(1,sizeof(*t)); + texObj->DriverData = t; + if ( t != NULL ) { + + /* Initialize non-image-dependent parts of the state: + */ + t->globj = texObj; + + /* FIXME Something here to set initial values for other parts of + * FIXME t->setup? + */ + + make_empty_list( t ); + + savageSetTexWrapping(t,texObj->WrapS,texObj->WrapT); + savageSetTexFilter(t,texObj->MinFilter,texObj->MagFilter); + savageSetTexBorderColor(t,texObj->_BorderChan); + } + + return t; +} + +/* Called by the _mesa_store_teximage[123]d() functions. */ +static const struct gl_texture_format * +savageChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + const GLboolean do32bpt = GL_FALSE; + const GLboolean force16bpt = GL_FALSE; + const GLboolean isSavage4 = (imesa->savageScreen->chipset >= S3_SAVAGE4); + (void) format; + (void) type; + + switch ( internalFormat ) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + switch ( type ) { + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555; + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return &_mesa_texformat_argb4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return &_mesa_texformat_argb1555; + default: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + } + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + switch ( type ) { + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return &_mesa_texformat_argb4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return &_mesa_texformat_argb1555; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + return &_mesa_texformat_rgb565; + default: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; + } + + case GL_RGBA8: + case GL_RGBA12: + case GL_RGBA16: + return !force16bpt ? + &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case GL_RGB10_A2: + return !force16bpt ? + &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555; + + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; + + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; + + case GL_RGB5: + case GL_RGB4: + case GL_R3_G3_B2: + return &_mesa_texformat_rgb565; + + case GL_ALPHA: + case GL_COMPRESSED_ALPHA: + return isSavage4 ? &_mesa_texformat_a8 : ( + do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444); + case GL_ALPHA4: + return isSavage4 ? &_mesa_texformat_a8 : &_mesa_texformat_argb4444; + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return isSavage4 ? &_mesa_texformat_a8 : ( + !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444); + + case 1: + case GL_LUMINANCE: + case GL_COMPRESSED_LUMINANCE: + /* no alpha, but use argb1555 in 16bit case to get pure grey values */ + return isSavage4 ? &_mesa_texformat_l8 : ( + do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555); + case GL_LUMINANCE4: + return isSavage4 ? &_mesa_texformat_l8 : &_mesa_texformat_argb1555; + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return isSavage4 ? &_mesa_texformat_l8 : ( + !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555); + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_COMPRESSED_LUMINANCE_ALPHA: + /* Savage4 has a al44 texture format. But it's not supported by Mesa. */ + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + return &_mesa_texformat_argb4444; + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case GL_INTENSITY: + case GL_COMPRESSED_INTENSITY: + return isSavage4 ? &_mesa_texformat_i8 : ( + do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444); + case GL_INTENSITY4: + return isSavage4 ? &_mesa_texformat_i8 : &_mesa_texformat_argb4444; + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return isSavage4 ? &_mesa_texformat_i8 : ( + !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444); +/* + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return &_mesa_texformat_ci8; +*/ + default: + _mesa_problem(ctx, "unexpected texture format in %s", __FUNCTION__); + return NULL; + } +} + +static void savageSetTexImages( savageContextPtr imesa, + const struct gl_texture_object *tObj ) +{ + savageTextureObjectPtr t = (savageTextureObjectPtr) tObj->DriverData; + struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; + GLuint offset, width, pitch, i, textureFormat, log_pitch; + + assert(t); + assert(image); + + switch (image->TexFormat->MesaFormat) { + case MESA_FORMAT_ARGB8888: + textureFormat = TFT_ARGB8888; + t->texelBytes = 4; + break; + case MESA_FORMAT_ARGB1555: + textureFormat = TFT_ARGB1555; + t->texelBytes = 2; + break; + case MESA_FORMAT_ARGB4444: + textureFormat = TFT_ARGB4444; + t->texelBytes = 2; + break; + case MESA_FORMAT_RGB565: + textureFormat = TFT_RGB565; + t->texelBytes = 2; + break; + case MESA_FORMAT_L8: + textureFormat = TFT_L8; + t->texelBytes = 1; + break; + case MESA_FORMAT_I8: + textureFormat = TFT_I8; + t->texelBytes = 1; + break; + case MESA_FORMAT_A8: + textureFormat = TFT_A8; + t->texelBytes = 1; + break; + default: + _mesa_problem(imesa->glCtx, "Bad texture format in %s", __FUNCTION__); + } + + /* Figure out the size now (and count the levels). Upload won't be done + * until later. + */ + width = image->Width * t->texelBytes; + for (pitch = 2, log_pitch=1 ; pitch < width ; pitch *= 2 ) + log_pitch++; + + t->dirty_images = 0; + t->bound = 0; + + offset = 0; + for ( i = 0 ; i < SAVAGE_TEX_MAXLEVELS && tObj->Image[0][i] ; i++ ) { + t->image[i].image = tObj->Image[0][i]; + t->image[i].offset = offset; + t->image[i].internalFormat = textureFormat; + t->dirty_images |= (1<<i); + offset += t->image[i].image->Height * pitch; + pitch = pitch >> 1; + } + + t->totalSize = offset; + t->max_level = i-1; + t->min_level = 0; +} + +void savageDestroyTexObj(savageContextPtr imesa, savageTextureObjectPtr t) +{ + if (!t) return; + + /* This is sad - need to sync *in case* we upload a texture + * to this newly free memory... + */ + if (t->MemBlock) { + mmFreeMem(t->MemBlock); + t->MemBlock = 0; + + if (t->age > imesa->dirtyAge) + imesa->dirtyAge = t->age; + } + + if (t->globj) + t->globj->DriverData = 0; + + if (t->bound) + imesa->CurrentTexObj[t->bound - 1] = 0; + + remove_from_list(t); + free(t); +} + + +static void savageSwapOutTexObj(savageContextPtr imesa, savageTextureObjectPtr t) +{ + if (t->MemBlock) { + mmFreeMem(t->MemBlock); + t->MemBlock = 0; + + if (t->age > imesa->dirtyAge) + imesa->dirtyAge = t->age; + } + + t->dirty_images = ~0; + move_to_tail(&(imesa->SwappedOut), t); +} + + + +/* Upload an image from mesa's internal copy. + */ +static void savageUploadTexLevel( savageTextureObjectPtr t, int level ) +{ + const struct gl_texture_image *image = t->image[level].image; + + + /* Need triangle (rather than pixel) fallbacks to simulate this using + * normal textured triangles. + * + * DO THIS IN DRIVER STATE MANAGMENT, not hardware state. + * + */ + + if(image->Border != 0) + fprintf (stderr, "Not supported texture border %d.\n", + (int) image->Border); + + savageTileTex(t, level); +} + + + +void savagePrintLocalLRU( savageContextPtr imesa , GLuint heap) +{ + savageTextureObjectPtr t; + int sz = 1 << (imesa->savageScreen->logTextureGranularity[heap]); + + foreach( t, &imesa->TexObjList[heap] ) { + if (!t->globj) + fprintf(stderr, "Placeholder %d at %x sz %x\n", + t->MemBlock->ofs / sz, + t->MemBlock->ofs, + t->MemBlock->size); + else + fprintf(stderr, "Texture (bound %d) at %x sz %x\n", + t->bound, + t->MemBlock->ofs, + t->MemBlock->size); + + } +} + +void savagePrintGlobalLRU( savageContextPtr imesa , GLuint heap) +{ + int i, j; + + drm_savage_tex_region_t *list = imesa->sarea->texList[heap]; + + + for (i = 0, j = SAVAGE_NR_TEX_REGIONS ; i < SAVAGE_NR_TEX_REGIONS ; i++) { + fprintf(stderr, "list[%d] age %d next %d prev %d\n", + j, list[j].age, list[j].next, list[j].prev); + j = list[j].next; + if (j == SAVAGE_NR_TEX_REGIONS) break; + } + + if (j != SAVAGE_NR_TEX_REGIONS) + fprintf(stderr, "Loop detected in global LRU\n"); + for (i = 0 ; i < SAVAGE_NR_TEX_REGIONS ; i++) + { + fprintf(stderr,"list[%d] age %d next %d prev %d\n", + i, list[i].age, list[i].next, list[i].prev); + } +} + + +void savageResetGlobalLRU( savageContextPtr imesa, GLuint heap ) +{ + drm_savage_tex_region_t *list = imesa->sarea->texList[heap]; + int sz = 1 << imesa->savageScreen->logTextureGranularity[heap]; + int i; + + /* (Re)initialize the global circular LRU list. The last element + * in the array (SAVAGE_NR_TEX_REGIONS) is the sentinal. Keeping it + * at the end of the array allows it to be addressed rationally + * when looking up objects at a particular location in texture + * memory. + */ + for (i = 0 ; (i+1) * sz <= imesa->savageScreen->textureSize[heap]; i++) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = SAVAGE_NR_TEX_REGIONS; + list[i].prev = i-1; + list[i].next = SAVAGE_NR_TEX_REGIONS; + list[SAVAGE_NR_TEX_REGIONS].prev = i; + list[SAVAGE_NR_TEX_REGIONS].next = 0; + imesa->sarea->texAge[heap] = 0; +} + + +static void savageUpdateTexLRU( savageContextPtr imesa, savageTextureObjectPtr t ) +{ + int i; + int heap = t->heap; + int logsz = imesa->savageScreen->logTextureGranularity[heap]; + int start = t->MemBlock->ofs >> logsz; + int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz; + drm_savage_tex_region_t *list = imesa->sarea->texList[heap]; + + imesa->texAge[heap] = ++imesa->sarea->texAge[heap]; + + /* Update our local LRU + */ + move_to_head( &(imesa->TexObjList[heap]), t ); + + /* Update the global LRU + */ + for (i = start ; i <= end ; i++) { + + list[i].in_use = 1; + list[i].age = imesa->texAge[heap]; + + /* remove_from_list(i) + */ + list[(unsigned)list[i].next].prev = list[i].prev; + list[(unsigned)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) + */ + list[i].prev = SAVAGE_NR_TEX_REGIONS; + list[i].next = list[SAVAGE_NR_TEX_REGIONS].next; + list[(unsigned)list[SAVAGE_NR_TEX_REGIONS].next].prev = i; + list[SAVAGE_NR_TEX_REGIONS].next = i; + } +} + + +/* Called for every shared texture region which has increased in age + * since we last held the lock. + * + * Figures out which of our textures have been ejected by other clients, + * and pushes a placeholder texture onto the LRU list to represent + * the other client's textures. + */ +void savageTexturesGone( savageContextPtr imesa, + GLuint heap, + GLuint offset, + GLuint size, + GLuint in_use ) +{ + savageTextureObjectPtr t, tmp; + + foreach_s ( t, tmp, &imesa->TexObjList[heap] ) { + + if (t->MemBlock->ofs >= offset + size || + t->MemBlock->ofs + t->MemBlock->size <= offset) + continue; + + /* It overlaps - kick it off. Need to hold onto the currently bound + * objects, however. + */ + if (t->bound) + savageSwapOutTexObj( imesa, t ); + else + savageDestroyTexObj( imesa, t ); + } + + + if (in_use) { + t = (savageTextureObjectPtr) calloc(1,sizeof(*t)); + if (!t) return; + + t->heap = heap; + t->MemBlock = mmAllocMem( imesa->texHeap[heap], size, 0, offset); + if(!t->MemBlock) + { + free(t); + return; + } + insert_at_head( &imesa->TexObjList[heap], t ); + } +} + + + + + +/* 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 savageUploadTexImages( savageContextPtr imesa, savageTextureObjectPtr t ) +{ + int heap; + int i; + int ofs; + + heap = t->heap = SAVAGE_CARD_HEAP; + + /* Do we need to eject LRU texture objects? + */ + if (!t->MemBlock) { + while (1) + { + t->MemBlock = mmAllocMem( imesa->texHeap[heap], t->totalSize, 12, 0 ); + if (t->MemBlock) + break; + else + { + heap = t->heap = SAVAGE_AGP_HEAP; + t->MemBlock = mmAllocMem( imesa->texHeap[heap], t->totalSize, 12, 0 ); + + if (t->MemBlock) + break; + } + + if (imesa->TexObjList[heap].prev->bound) { + fprintf(stderr, "Hit bound texture in upload\n"); + savagePrintLocalLRU( imesa,heap ); + return -1; + } + + if (imesa->TexObjList[heap].prev == &(imesa->TexObjList[heap])) { + fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); + mmDumpMemInfo( imesa->texHeap[heap] ); + return -1; + } + + savageDestroyTexObj( imesa, imesa->TexObjList[heap].prev ); + } + + ofs = t->MemBlock->ofs; + t->texParams.hwPhysAddress = imesa->savageScreen->textureOffset[heap] + ofs; + t->BufAddr = (char *)((GLuint) imesa->savageScreen->texVirtual[heap] + ofs); + imesa->dirty |= SAVAGE_UPLOAD_CTX; + } + + /* Let the world know we've used this memory recently. + */ + savageUpdateTexLRU( imesa, t ); + + if (t->dirty_images) { + if (SAVAGE_DEBUG & DEBUG_VERBOSE_LRU) + fprintf(stderr, "*"); + + for (i = t->min_level ; i <= t->max_level ; i++) + if (t->dirty_images & (1<<i)) + savageUploadTexLevel( t, i ); + } + + + t->dirty_images = 0; + return 0; +} + +static void savageTexSetUnit( savageTextureObjectPtr t, GLuint unit ) +{ + if (t->current_unit == unit) return; + + t->current_unit = unit; +} + + + + +static void savageUpdateTex0State_s4( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + struct gl_texture_object *tObj; + savageTextureObjectPtr t; + GLuint format; + Reg_TexCtrl TexCtrl; + Reg_TexBlendCtrl TexBlendCtrl; + Reg_TexDescr TexDescr; + + /* disable */ + + if (ctx->Texture.Unit[0]._ReallyEnabled == 0) { + imesa->Registers.TexDescr.s4.tex0En = GL_FALSE; + imesa->Registers.TexBlendCtrl[0].ui = TBC_NoTexMap; + imesa->Registers.TexCtrl[0].ui = 0x20f040; + imesa->Registers.TexAddr[0].ui = 0; + imesa->Registers.changed.ni.fTex0BlendCtrlChanged = GL_TRUE; + imesa->Registers.changed.ni.fTex0AddrChanged = GL_TRUE; + imesa->Registers.changed.ni.fTexDescrChanged = GL_TRUE; + imesa->Registers.changed.ni.fTex0CtrlChanged = GL_TRUE; + return; + } + + tObj = ctx->Texture.Unit[0]._Current; + if (ctx->Texture.Unit[0]._ReallyEnabled != TEXTURE_2D_BIT || + tObj->Image[0][tObj->BaseLevel]->Border > 0) { + /* 1D or 3D texturing enabled, or texture border - fallback */ + FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); + return; + } + + /* Do 2D texture setup */ + + t = tObj->DriverData; + if (!t) { + t = savageAllocTexObj( tObj ); + if (!t) + return; + } + + if (t->current_unit != 0) + savageTexSetUnit( t, 0 ); + + imesa->CurrentTexObj[0] = t; + t->bound = 1; + + if (t->dirty_images) { + savageSetTexImages(imesa, tObj); + savageUploadTexImages(imesa, imesa->CurrentTexObj[0]); + } + + if (t->MemBlock) + savageUpdateTexLRU( imesa, t ); + + TexDescr.ui = imesa->Registers.TexDescr.ui & ~0x01000000; + TexCtrl.ui = imesa->Registers.TexCtrl[0].ui; + TexBlendCtrl.ui = imesa->Registers.TexBlendCtrl[0].ui; + + format = tObj->Image[0][tObj->BaseLevel]->Format; + + switch (ctx->Texture.Unit[0].EnvMode) { + case GL_REPLACE: + TexCtrl.s4.clrArg1Invert = GL_FALSE; + switch(format) + { + case GL_LUMINANCE: + case GL_RGB: + TexBlendCtrl.ui = TBC_Decal; + break; + + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + case GL_INTENSITY: + TexBlendCtrl.ui = TBC_Copy; + break; + + case GL_ALPHA: + TexBlendCtrl.ui = TBC_CopyAlpha; + break; + } + __HWEnvCombineSingleUnitScale(imesa, 0, 0, &TexBlendCtrl); + break; + + case GL_DECAL: + TexCtrl.s4.clrArg1Invert = GL_FALSE; + switch (format) + { + case GL_RGB: + case GL_LUMINANCE: + TexBlendCtrl.ui = TBC_Decal; + break; + + case GL_RGBA: + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + TexBlendCtrl.ui = TBC_DecalAlpha; + break; + + /* + GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_INTENSITY + are undefined with GL_DECAL + */ + + case GL_ALPHA: + TexBlendCtrl.ui = TBC_CopyAlpha; + break; + } + __HWEnvCombineSingleUnitScale(imesa, 0, 0, &TexBlendCtrl); + break; + + case GL_MODULATE: + TexCtrl.s4.clrArg1Invert = GL_FALSE; + TexBlendCtrl.ui = TBC_ModulAlpha; + __HWEnvCombineSingleUnitScale(imesa, 0, 0, &TexBlendCtrl); + break; + + case GL_BLEND: + + switch (format) + { + case GL_ALPHA: + TexBlendCtrl.ui = TBC_ModulAlpha; + TexCtrl.s4.clrArg1Invert = GL_FALSE; + break; + + case GL_LUMINANCE: + case GL_RGB: + TexBlendCtrl.ui = TBC_Blend0; + TexDescr.s4.tex1En = GL_TRUE; + TexDescr.s4.texBLoopEn = GL_TRUE; + TexDescr.s4.tex1Width = TexDescr.s4.tex0Width; + TexDescr.s4.tex1Height = TexDescr.s4.tex0Height; + TexDescr.s4.tex1Fmt = TexDescr.s4.tex0Fmt; + + if (imesa->Registers.TexAddr[1].ui != imesa->Registers.TexAddr[0].ui) + { + imesa->Registers.TexAddr[1].ui = imesa->Registers.TexAddr[0].ui; + imesa->Registers.changed.ni.fTex1AddrChanged = GL_TRUE; + } + + if (imesa->Registers.TexBlendCtrl[1].ui != TBC_Blend1) + { + imesa->Registers.TexBlendCtrl[1].ui = TBC_Blend1; + imesa->Registers.changed.ni.fTex1BlendCtrlChanged = GL_TRUE; + } + + TexCtrl.s4.clrArg1Invert = GL_TRUE; + imesa->bTexEn1 = GL_TRUE; + break; + + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + TexBlendCtrl.ui = TBC_BlendAlpha0; + TexDescr.s4.tex1En = GL_TRUE; + TexDescr.s4.texBLoopEn = GL_TRUE; + TexDescr.s4.tex1Width = TexDescr.s4.tex0Width; + TexDescr.s4.tex1Height = TexDescr.s4.tex0Height; + TexDescr.s4.tex1Fmt = TexDescr.s4.tex0Fmt; + + if (imesa->Registers.TexAddr[1].ui != imesa->Registers.TexAddr[0].ui) + { + imesa->Registers.TexAddr[1].ui = imesa->Registers.TexAddr[0].ui; + imesa->Registers.changed.ni.fTex1AddrChanged = GL_TRUE; + } + + if (imesa->Registers.TexBlendCtrl[1].ui != TBC_BlendAlpha1) + { + imesa->Registers.TexBlendCtrl[1].ui = TBC_BlendAlpha1; + imesa->Registers.changed.ni.fTex1BlendCtrlChanged = GL_TRUE; + } + + TexCtrl.s4.clrArg1Invert = GL_TRUE; + imesa->bTexEn1 = GL_TRUE; + break; + + case GL_INTENSITY: + TexBlendCtrl.ui = TBC_BlendInt0; + TexDescr.s4.tex1En = GL_TRUE; + TexDescr.s4.texBLoopEn = GL_TRUE; + TexDescr.s4.tex1Width = TexDescr.s4.tex0Width; + TexDescr.s4.tex1Height = TexDescr.s4.tex0Height; + TexDescr.s4.tex1Fmt = TexDescr.s4.tex0Fmt; + + if (imesa->Registers.TexAddr[1].ui != imesa->Registers.TexAddr[0].ui) + { + imesa->Registers.TexAddr[1].ui = imesa->Registers.TexAddr[0].ui; + imesa->Registers.changed.ni.fTex1AddrChanged = GL_TRUE; + } + + if (imesa->Registers.TexBlendCtrl[1].ui != TBC_BlendInt1) + { + imesa->Registers.TexBlendCtrl[1].ui = TBC_BlendInt1; + imesa->Registers.changed.ni.fTex1BlendCtrlChanged = GL_TRUE; + } + TexCtrl.s4.clrArg1Invert = GL_TRUE; + TexCtrl.s4.alphaArg1Invert = GL_TRUE; + imesa->bTexEn1 = GL_TRUE; + break; + } + __HWEnvCombineSingleUnitScale(imesa, 0, 0, &TexBlendCtrl); + break; + + /* + GL_ADD + */ + case GL_ADD: + printf("Add\n"); + TexCtrl.s4.clrArg1Invert = GL_FALSE; + TexBlendCtrl.ui = TBC_AddAlpha; + __HWEnvCombineSingleUnitScale(imesa, 0, 0, &TexBlendCtrl); + break; + +#if GL_ARB_texture_env_combine + case GL_COMBINE_ARB: + __HWParseTexEnvCombine(imesa, 0, &TexCtrl, &TexBlendCtrl); + break; +#endif + + default: + fprintf(stderr, "unknown tex env mode"); + exit(1); + break; + } + + TexCtrl.s4.uMode = !(t->texParams.sWrapMode & 0x01); + TexCtrl.s4.vMode = !(t->texParams.tWrapMode & 0x01); + + switch (t->texParams.minFilter) + { + case GL_NEAREST: + TexCtrl.s4.filterMode = TFM_Point; + TexCtrl.s4.mipmapEnable = GL_FALSE; + break; + + case GL_LINEAR: + TexCtrl.s4.filterMode = TFM_Bilin; + TexCtrl.s4.mipmapEnable = GL_FALSE; + break; + + case GL_NEAREST_MIPMAP_NEAREST: + TexCtrl.s4.filterMode = TFM_Point; + TexCtrl.s4.mipmapEnable = GL_TRUE; + break; + + case GL_LINEAR_MIPMAP_NEAREST: + TexCtrl.s4.filterMode = TFM_Bilin; + TexCtrl.s4.mipmapEnable = GL_TRUE; + break; + + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_LINEAR: + TexCtrl.s4.filterMode = TFM_Trilin; + TexCtrl.s4.mipmapEnable = GL_TRUE; + break; + } + + if((ctx->Texture.Unit[0].LodBias !=0.0F) && (TexCtrl.s4.dBias != 0)) + { + union { + GLfloat f; + GLint i; + } bias; + GLuint ul; + + bias.f = ctx->Texture.Unit[0].LodBias; + + /* if the value is >= 15.9375 determine whether >= 16 + or <0 + */ + if(((bias.i) & 0x7FFFFFFF) >= 0x417F0000) + { + if((bias.i) & 0x80000000) + { + ul=0x101; + } + else + { + ul=0xff; + } + } + else + { + ul=(GLuint)(bias.f*16.0); + } + + ul &= 0x1FF; + TexCtrl.s4.dBias = ul; + } + + TexDescr.s4.tex0En = GL_TRUE; + TexDescr.s4.tex0Width = t->image[0].image->WidthLog2; + TexDescr.s4.tex0Height = t->image[0].image->HeightLog2; + TexDescr.s4.tex0Fmt = t->image[0].internalFormat; + TexCtrl.s4.dMax = t->max_level; + + if (TexDescr.s4.tex1En) + TexDescr.s4.texBLoopEn = GL_TRUE; + + if (imesa->Registers.TexAddr[0].ui != (GLuint)t->texParams.hwPhysAddress) + { + imesa->Registers.TexAddr[0].ui = (GLuint) t->texParams.hwPhysAddress | 0x2; + + if(t->heap == SAVAGE_AGP_HEAP) + imesa->Registers.TexAddr[0].ui |= 0x1; + + imesa->Registers.changed.ni.fTex0AddrChanged = GL_TRUE; + } + + if (imesa->Registers.TexCtrl[0].ui != TexCtrl.ui) + { + imesa->Registers.TexCtrl[0].ui = TexCtrl.ui; + imesa->Registers.changed.ni.fTex0CtrlChanged = GL_TRUE; + } + + if (imesa->Registers.TexBlendCtrl[0].ui != TexBlendCtrl.ui) + { + imesa->Registers.TexBlendCtrl[0].ui = TexBlendCtrl.ui; + imesa->Registers.changed.ni.fTex0BlendCtrlChanged = GL_TRUE; + } + + if (imesa->Registers.TexDescr.ui != TexDescr.ui) + { + imesa->Registers.TexDescr.ui = TexDescr.ui; + imesa->Registers.changed.ni.fTexDescrChanged = GL_TRUE; + } + + return; +} +static void savageUpdateTex1State_s4( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + struct gl_texture_object *tObj; + savageTextureObjectPtr t; + GLuint format; + Reg_TexCtrl TexCtrl; + Reg_TexBlendCtrl TexBlendCtrl; + Reg_TexDescr TexDescr; + + + /* disable */ + if(imesa->bTexEn1) + { + imesa->bTexEn1 = GL_FALSE; + return; + } + + if (ctx->Texture.Unit[1]._ReallyEnabled == 0) { + imesa->Registers.TexDescr.s4.tex1En = GL_FALSE; + imesa->Registers.TexBlendCtrl[1].ui = TBC_NoTexMap1; + imesa->Registers.TexCtrl[1].ui = 0x20f040; + imesa->Registers.TexAddr[1].ui = 0; + imesa->Registers.TexDescr.s4.texBLoopEn = GL_FALSE; + imesa->Registers.changed.ni.fTex1BlendCtrlChanged = GL_TRUE; + imesa->Registers.changed.ni.fTexDescrChanged = GL_TRUE; + imesa->Registers.changed.ni.fTex1BlendCtrlChanged = GL_TRUE; + imesa->Registers.changed.ni.fTex1AddrChanged = GL_TRUE; + return; + } + + tObj = ctx->Texture.Unit[1]._Current; + + if (ctx->Texture.Unit[1]._ReallyEnabled != TEXTURE_2D_BIT || + tObj->Image[0][tObj->BaseLevel]->Border > 0) { + /* 1D or 3D texturing enabled, or texture border - fallback */ + FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); + return; + } + + /* Do 2D texture setup */ + + t = tObj->DriverData; + if (!t) { + t = savageAllocTexObj( tObj ); + if (!t) + return; + } + + if (t->current_unit != 1) + savageTexSetUnit( t, 1 ); + + imesa->CurrentTexObj[1] = t; + + t->bound = 2; + + if (t->dirty_images) { + savageSetTexImages(imesa, tObj); + savageUploadTexImages(imesa, imesa->CurrentTexObj[1]); + } + + if (t->MemBlock) + savageUpdateTexLRU( imesa, t ); + + TexDescr.ui = imesa->Registers.TexDescr.ui; + TexCtrl.ui = imesa->Registers.TexCtrl[1].ui; + TexBlendCtrl.ui = imesa->Registers.TexBlendCtrl[1].ui; + + format = tObj->Image[0][tObj->BaseLevel]->Format; + + switch (ctx->Texture.Unit[1].EnvMode) { + case GL_REPLACE: + TexCtrl.s4.clrArg1Invert = GL_FALSE; + switch (format) + { + case GL_LUMINANCE: + case GL_RGB: + TexBlendCtrl.ui = TBC_Decal; + break; + + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + case GL_RGBA: + TexBlendCtrl.ui = TBC_Copy; + break; + + case GL_ALPHA: + TexBlendCtrl.ui = TBC_CopyAlpha1; + break; + } + __HWEnvCombineSingleUnitScale(imesa, 0, 1, &TexBlendCtrl); + break; + case GL_MODULATE: + TexCtrl.s4.clrArg1Invert = GL_FALSE; + TexBlendCtrl.ui = TBC_ModulAlpha1; + __HWEnvCombineSingleUnitScale(imesa, 0, 1, &TexBlendCtrl); + break; + +/*#if GL_EXT_texture_env_add*/ + case GL_ADD: + TexCtrl.s4.clrArg1Invert = GL_FALSE; + TexBlendCtrl.ui = TBC_AddAlpha1; + __HWEnvCombineSingleUnitScale(imesa, 0, 1, &TexBlendCtrl); + break; +/*#endif*/ + +#if GL_ARB_texture_env_combine + case GL_COMBINE_ARB: + __HWParseTexEnvCombine(imesa, 1, &TexCtrl, &TexBlendCtrl); + break; +#endif + + case GL_DECAL: + TexCtrl.s4.clrArg1Invert = GL_FALSE; + + switch (format) + { + case GL_LUMINANCE: + case GL_RGB: + TexBlendCtrl.ui = TBC_Decal1; + break; + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + case GL_RGBA: + TexBlendCtrl.ui = TBC_DecalAlpha1; + break; + + /* + // GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_INTENSITY + // are undefined with GL_DECAL + */ + case GL_ALPHA: + TexBlendCtrl.ui = TBC_CopyAlpha1; + break; + } + __HWEnvCombineSingleUnitScale(imesa, 0, 1, &TexBlendCtrl); + break; + + case GL_BLEND: + if (format == GL_LUMINANCE) + { + /* + // This is a hack for GLQuake, invert. + */ + TexCtrl.s4.clrArg1Invert = GL_TRUE; + TexBlendCtrl.ui = 0; + } + __HWEnvCombineSingleUnitScale(imesa, 0, 1, &TexBlendCtrl); + break; + + default: + fprintf(stderr, "unkown tex 1 env mode\n"); + exit(1); + break; + } + + TexCtrl.s4.uMode = !(t->texParams.sWrapMode & 0x01); + TexCtrl.s4.vMode = !(t->texParams.tWrapMode & 0x01); + + switch (t->texParams.minFilter) + { + case GL_NEAREST: + TexCtrl.s4.filterMode = TFM_Point; + TexCtrl.s4.mipmapEnable = GL_FALSE; + break; + + case GL_LINEAR: + TexCtrl.s4.filterMode = TFM_Bilin; + TexCtrl.s4.mipmapEnable = GL_FALSE; + break; + + case GL_NEAREST_MIPMAP_NEAREST: + TexCtrl.s4.filterMode = TFM_Point; + TexCtrl.s4.mipmapEnable = GL_TRUE; + break; + + case GL_LINEAR_MIPMAP_NEAREST: + TexCtrl.s4.filterMode = TFM_Bilin; + TexCtrl.s4.mipmapEnable = GL_TRUE; + break; + + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_LINEAR: + TexCtrl.s4.filterMode = TFM_Trilin; + TexCtrl.s4.mipmapEnable = GL_TRUE; + break; + } + + if((ctx->Texture.Unit[1].LodBias !=0.0F)&&(TexCtrl.s4.dBias != 0)) + { + union { + GLfloat f; + GLint i; + } bias; + GLuint ul; + + bias.f = ctx->Texture.Unit[1].LodBias; + + /* if the value is >= 15.9375 determine whether >= 16 + or <0 + */ + if(((bias.i) & 0x7FFFFFFF) >= 0x417F0000) + { + if((bias.i) & 0x80000000) + { + ul=0x101; + } + else + { + ul=0xff; + } + } + else + { + ul=(GLuint)(bias.f*16.0); + } + + ul &= 0x1FF; + TexCtrl.s4.dBias = ul; + } + + TexDescr.s4.tex1En = GL_TRUE; + TexDescr.s4.tex1Width = t->image[0].image->WidthLog2; + TexDescr.s4.tex1Height = t->image[0].image->HeightLog2; + TexDescr.s4.tex1Fmt = t->image[0].internalFormat; + TexCtrl.s4.dMax = t->max_level; + TexDescr.s4.texBLoopEn = GL_TRUE; + + if (imesa->Registers.TexAddr[1].ui != (GLuint)t->texParams.hwPhysAddress) + { + imesa->Registers.TexAddr[1].ui = (GLuint) t->texParams.hwPhysAddress| 2; + + if(t->heap == SAVAGE_AGP_HEAP) + imesa->Registers.TexAddr[1].ui |= 0x1; + + /*imesa->Registers.TexAddr[1].ui = (GLuint) t->texParams.hwPhysAddress| 3;*/ + imesa->Registers.changed.ni.fTex1AddrChanged = GL_TRUE; + } + + if (imesa->Registers.TexCtrl[1].ui != TexCtrl.ui) + { + imesa->Registers.TexCtrl[1].ui = TexCtrl.ui; + imesa->Registers.changed.ni.fTex1CtrlChanged = GL_TRUE; + } + + if (imesa->Registers.TexBlendCtrl[1].ui != TexBlendCtrl.ui) + { + imesa->Registers.TexBlendCtrl[1].ui = TexBlendCtrl.ui; + imesa->Registers.changed.ni.fTex1BlendCtrlChanged = GL_TRUE; + } + + if (imesa->Registers.TexDescr.ui != TexDescr.ui) + { + imesa->Registers.TexDescr.ui = TexDescr.ui; + imesa->Registers.changed.ni.fTexDescrChanged = GL_TRUE; + } + +} +static void savageUpdateTexState_s3d( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + struct gl_texture_object *tObj; + savageTextureObjectPtr t; + GLuint format; + Reg_TexCtrl TexCtrl; + Reg_DrawCtrl DrawCtrl; + Reg_TexDescr TexDescr; + + /* disable */ + if (ctx->Texture.Unit[0]._ReallyEnabled == 0) { + imesa->Registers.TexCtrl[0].ui = 0; + imesa->Registers.TexCtrl[0].s3d.texEn = GL_FALSE; + imesa->Registers.TexCtrl[0].s3d.dBias = 0x08; + imesa->Registers.TexCtrl[0].s3d.texXprEn = GL_TRUE; + imesa->Registers.TexAddr[0].ui = 0; + imesa->Registers.changed.ni.fTex0AddrChanged = GL_TRUE; + imesa->Registers.changed.ni.fTex0CtrlChanged = GL_TRUE; + return; + } + + tObj = ctx->Texture.Unit[0]._Current; + if (ctx->Texture.Unit[0]._ReallyEnabled != TEXTURE_2D_BIT || + tObj->Image[0][tObj->BaseLevel]->Border > 0) { + /* 1D or 3D texturing enabled, or texture border - fallback */ + FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); + return; + } + + /* Do 2D texture setup */ + t = tObj->DriverData; + if (!t) { + t = savageAllocTexObj( tObj ); + if (!t) + return; + } + + if (t->current_unit != 0) + savageTexSetUnit( t, 0 ); + + imesa->CurrentTexObj[0] = t; + t->bound = 1; + + if (t->dirty_images) { + savageSetTexImages(imesa, tObj); + savageUploadTexImages(imesa, imesa->CurrentTexObj[0]); + } + + if (t->MemBlock) + savageUpdateTexLRU( imesa, t ); + + TexDescr.ui = imesa->Registers.TexDescr.ui; + TexCtrl.ui = imesa->Registers.TexCtrl[0].ui; + DrawCtrl.ui = imesa->Registers.DrawCtrl.ui; + + format = tObj->Image[0][tObj->BaseLevel]->Format; + + /* FIXME: copied from utah-glx, probably needs some tuning */ + switch (ctx->Texture.Unit[0].EnvMode) { + case GL_DECAL: + DrawCtrl.ni.texBlendCtrl = SAVAGETBC_DECAL_S3D; + break; + case GL_REPLACE: + DrawCtrl.ni.texBlendCtrl = SAVAGETBC_COPY_S3D; + break; + case GL_BLEND: /* FIXIT */ + case GL_MODULATE: + DrawCtrl.ni.texBlendCtrl = SAVAGETBC_MODULATEALPHA_S3D; + break; + default: + fprintf(stderr, "unkown tex env mode\n"); + /*exit(1);*/ + break; + } + + DrawCtrl.ni.flushPdDestWrites = GL_TRUE; + DrawCtrl.ni.flushPdZbufWrites = GL_TRUE; + + /* FIXME: this is how the utah-driver works. I doubt it's the ultimate + truth. */ + TexCtrl.s3d.uWrapEn = 0; + TexCtrl.s3d.vWrapEn = 0; + if (t->texParams.sWrapMode == GL_CLAMP) + TexCtrl.s3d.wrapMode = TAM_Clamp; + else + TexCtrl.s3d.wrapMode = TAM_Wrap; + + switch (t->texParams.minFilter) { + case GL_NEAREST: + TexCtrl.s3d.filterMode = TFM_Point; + TexCtrl.s3d.mipmapDisable = GL_TRUE; + break; + + case GL_LINEAR: + TexCtrl.s3d.filterMode = TFM_Bilin; + TexCtrl.s3d.mipmapDisable = GL_TRUE; + break; + + case GL_NEAREST_MIPMAP_NEAREST: + TexCtrl.s3d.filterMode = TFM_Point; + TexCtrl.s3d.mipmapDisable = GL_FALSE; + break; + + case GL_LINEAR_MIPMAP_NEAREST: + TexCtrl.s3d.filterMode = TFM_Bilin; + TexCtrl.s3d.mipmapDisable = GL_FALSE; + break; + + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_LINEAR: + TexCtrl.s3d.filterMode = TFM_Trilin; + TexCtrl.s3d.mipmapDisable = GL_FALSE; + break; + } + + /* There is no way to specify a maximum mipmap level. We may have to + disable mipmapping completely. */ + /* + if (t->max_level < t->image[0].image->WidthLog2 || + t->max_level < t->image[0].image->HeightLog2) { + TexCtrl.s3d.mipmapEnable = GL_TRUE; + if (TexCtrl.s3d.filterMode == TFM_Trilin) + TexCtrl.s3d.filterMode = TFM_Bilin; + TexCtrl.s3d.filterMode = TFM_Point; + } + */ + + /* LOD bias makes corruption of small mipmap levels worse on Savage IX + * but doesn't show the desired effect with the lodbias mesa demo. */ + TexCtrl.s3d.dBias = 0; + + TexCtrl.s3d.texEn = GL_TRUE; + TexDescr.s3d.texWidth = t->image[0].image->WidthLog2; + TexDescr.s3d.texHeight = t->image[0].image->HeightLog2; + assert (t->image[0].internalFormat <= 7); + TexDescr.s3d.texFmt = t->image[0].internalFormat; + + if (imesa->Registers.TexAddr[0].ni.addr != (GLuint)t->texParams.hwPhysAddress >> 3) + { + imesa->Registers.TexAddr[0].ni.addr = (GLuint) t->texParams.hwPhysAddress >> 3; + + if(t->heap == SAVAGE_AGP_HEAP) { + imesa->Registers.TexAddr[0].ni.inSysTex = 1; + imesa->Registers.TexAddr[0].ni.inAGPTex = 1; + } else { + imesa->Registers.TexAddr[0].ni.inSysTex = 0; + imesa->Registers.TexAddr[0].ni.inAGPTex = 1; + } + + imesa->Registers.changed.ni.fTex0AddrChanged = GL_TRUE; + } + + if (imesa->Registers.TexCtrl[0].ui != TexCtrl.ui) + { + imesa->Registers.TexCtrl[0].ui = TexCtrl.ui; + imesa->Registers.changed.ni.fTex0CtrlChanged = GL_TRUE; + } + + if (imesa->Registers.TexDescr.ui != TexDescr.ui) + { + imesa->Registers.TexDescr.ui = TexDescr.ui; + imesa->Registers.changed.ni.fTexDescrChanged = GL_TRUE; + } + + if (imesa->Registers.DrawCtrl.ui != DrawCtrl.ui) + { + imesa->Registers.DrawCtrl.ui = DrawCtrl.ui; + imesa->Registers.changed.ni.fDrawCtrlChanged = GL_TRUE; + } +} + + + +static void savageUpdateTextureState_s4( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound = 0; + if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->bound = 0; + imesa->CurrentTexObj[0] = 0; + imesa->CurrentTexObj[1] = 0; + FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_FALSE); + savageUpdateTex0State_s4( ctx ); + savageUpdateTex1State_s4( ctx ); + imesa->dirty |= (SAVAGE_UPLOAD_CTX | + SAVAGE_UPLOAD_TEX0 | + SAVAGE_UPLOAD_TEX1); +} +static void savageUpdateTextureState_s3d( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound = 0; + imesa->CurrentTexObj[0] = 0; + if (ctx->Texture.Unit[1]._ReallyEnabled) { + FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE); + } else { + FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_FALSE); + savageUpdateTexState_s3d( ctx ); + imesa->dirty |= (SAVAGE_UPLOAD_CTX | + SAVAGE_UPLOAD_TEX0); + } +} +static void savageUpdateTextureState_first( GLcontext *ctx) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + if (imesa->savageScreen->chipset <= S3_SAVAGE4) { + GetTiledCoordinates16 = GetTiledCoordinates16_4; + GetTiledCoordinates32 = GetTiledCoordinates32_4; + } else { + GetTiledCoordinates16 = GetTiledCoordinates16_8; + GetTiledCoordinates32 = GetTiledCoordinates32_8; + } + if (imesa->savageScreen->chipset >= S3_SAVAGE4) + savageUpdateTextureState = savageUpdateTextureState_s4; + else + savageUpdateTextureState = savageUpdateTextureState_s3d; + savageUpdateTextureState (ctx); +} +void (*savageUpdateTextureState)( GLcontext *ctx ) = + savageUpdateTextureState_first; + + + +/***************************************** + * DRIVER functions + *****************************************/ + +static void savageTexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + + if (pname == GL_TEXTURE_ENV_MODE) { + + imesa->new_state |= SAVAGE_NEW_TEXTURE; + + } else if (pname == GL_TEXTURE_ENV_COLOR) { + + struct gl_texture_unit *texUnit = + &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + const 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)); + + + } +} + +static void savageTexImage2D( 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 ) +{ + savageTextureObjectPtr t = (savageTextureObjectPtr) texObj->DriverData; + if (t) { + savageSwapOutTexObj( SAVAGE_CONTEXT(ctx), t ); + } else { + t = savageAllocTexObj(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 ); + t->dirty_images |= (1 << level); + SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; +} + +static void savageTexSubImage2D( 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 ) +{ + savageTextureObjectPtr t = (savageTextureObjectPtr) texObj->DriverData; + assert( t ); /* this _should_ be true */ + if (t) { + savageSwapOutTexObj( SAVAGE_CONTEXT(ctx), t ); + } else { + t = savageAllocTexObj(texObj); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, + height, format, type, pixels, packing, texObj, + texImage); + t->dirty_images |= (1 << level); + SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE; +} + +static void savageTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) +{ + savageTextureObjectPtr t = (savageTextureObjectPtr) tObj->DriverData; + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + + if (!t || target != GL_TEXTURE_2D) + return; + + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + savageSetTexFilter(t,tObj->MinFilter,tObj->MagFilter); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + savageSetTexWrapping(t,tObj->WrapS,tObj->WrapT); + break; + + case GL_TEXTURE_BORDER_COLOR: + savageSetTexBorderColor(t,tObj->_BorderChan); + break; + + default: + return; + } + + imesa->new_state |= SAVAGE_NEW_TEXTURE; +} + +static void savageBindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + + + if (imesa->CurrentTexObj[ctx->Texture.CurrentUnit]) { + imesa->CurrentTexObj[ctx->Texture.CurrentUnit]->bound = 0; + imesa->CurrentTexObj[ctx->Texture.CurrentUnit] = 0; + } + + assert( (target != GL_TEXTURE_2D) || (tObj->DriverData != NULL) ); + + imesa->new_state |= SAVAGE_NEW_TEXTURE; +} + +static void savageDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) +{ + savageTextureObjectPtr t = (savageTextureObjectPtr)tObj->DriverData; + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + + if (t) { + + if (t->bound) { + imesa->CurrentTexObj[t->bound-1] = 0; + imesa->new_state |= SAVAGE_NEW_TEXTURE; + } + + savageDestroyTexObj(imesa,t); + tObj->DriverData=0; + } + /* Free mipmap images and the texture object itself */ + _mesa_delete_texture_object(ctx, tObj); +} + + +static GLboolean savageIsTextureResident( GLcontext *ctx, + struct gl_texture_object *t ) +{ + savageTextureObjectPtr mt; + +/* LOCK_HARDWARE; */ + mt = (savageTextureObjectPtr)t->DriverData; +/* UNLOCK_HARDWARE; */ + + return mt && mt->MemBlock; +} + + +static struct gl_texture_object * +savageNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) +{ + struct gl_texture_object *obj; + obj = _mesa_new_texture_object(ctx, name, target); + savageAllocTexObj( obj ); + + return obj; +} + +void savageDDInitTextureFuncs( struct dd_function_table *functions ) +{ + functions->TexEnv = savageTexEnv; + functions->ChooseTextureFormat = savageChooseTextureFormat; + functions->TexImage2D = savageTexImage2D; + functions->TexSubImage2D = savageTexSubImage2D; + functions->BindTexture = savageBindTexture; + functions->NewTextureObject = savageNewTextureObject; + functions->DeleteTexture = savageDeleteTexture; + functions->IsTextureResident = savageIsTextureResident; + functions->TexParameter = savageTexParameter; +} diff --git a/src/mesa/drivers/dri/savage/savagetex.h b/src/mesa/drivers/dri/savage/savagetex.h new file mode 100644 index 0000000000..9ff85e2e32 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagetex.h @@ -0,0 +1,117 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. 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 + * VIA, S3 GRAPHICS, 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. + */ + + +#ifndef SAVAGETEX_INC +#define SAVAGETEX_INC + +#include "mtypes.h" +#include "mm.h" + +#include "savagecontext.h" +#include "savage_3d_reg.h" + +#define VALID_SAVAGE_TEXTURE_OBJECT(tobj) (tobj) + +#define SAVAGE_TEX_MAXLEVELS 11 +#define MIN_TILE_CHUNK 8 +#define MIPMAP_CHUNK 4 + + + +/* 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' + */ +typedef struct { + GLuint sWrapMode; + GLuint tWrapMode; + GLuint minFilter; + GLuint magFilter; + GLuint boarderColor; + GLuint hwPhysAddress; +} savage_texture_parameter_t; + +struct savage_texture_object_t { + struct savage_texture_object_t *next, *prev; + struct gl_texture_object *globj; + GLuint age; + + + GLuint texelBytes; + GLuint totalSize; + GLuint bound; + GLuint heap; + + PMemBlock MemBlock; + char *BufAddr; + + GLuint min_level; + GLuint max_level; + GLuint dirty_images; + + struct { + const struct gl_texture_image *image; + GLuint offset; /* into BufAddr */ + GLuint height; + GLuint internalFormat; + } image[SAVAGE_TEX_MAXLEVELS]; + + /* Support for multitexture. + */ + GLuint current_unit; + savage_texture_parameter_t texParams; +}; + +#define SAVAGE_NO_PALETTE 0x0 +#define SAVAGE_USE_PALETTE 0x1 +#define SAVAGE_UPDATE_PALETTE 0x2 +#define SAVAGE_FALLBACK_PALETTE 0x4 +#define __HWEnvCombineSingleUnitScale(imesa, flag0, flag1, TexBlendCtrl) +#define __HWParseTexEnvCombine(imesa, flag0, TexCtrl, TexBlendCtrl) + + +extern void (*savageUpdateTextureState)( GLcontext *ctx ); +void savageDDInitTextureFuncs( struct dd_function_table *functions ); + +void savageDestroyTexObj( savageContextPtr imesa, savageTextureObjectPtr t); +int savageUploadTexImages( savageContextPtr imesa, savageTextureObjectPtr t ); + +void savageResetGlobalLRU( savageContextPtr imesa , GLuint heap); +void savageTexturesGone( savageContextPtr imesa, GLuint heap, + GLuint start, GLuint end, + GLuint in_use ); + +void savagePrintLocalLRU( savageContextPtr imesa ,GLuint heap); +void savagePrintGlobalLRU( savageContextPtr imesa ,GLuint heap); + +#endif diff --git a/src/mesa/drivers/dri/savage/savagetris.c b/src/mesa/drivers/dri/savage/savagetris.c new file mode 100644 index 0000000000..db061d9d39 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagetris.c @@ -0,0 +1,817 @@ +/* $XFree86$ */ /* -*- c-basic-offset: 3 -*- */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + 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 <keithw@valinux.com> + * Felix Kuehling <fxkuehl@gmx.de> + * + */ + +#include <stdio.h> +#include <math.h> + +#include "glheader.h" +#include "mtypes.h" +#include "colormac.h" +#include "macros.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "savagetris.h" +#include "savagestate.h" +#include "savagetex.h" +#include "savagevb.h" +#include "savageioctl.h" +#include "savage_bci.h" + +static void savageRasterPrimitive( GLcontext *ctx, GLuint prim ); +static void savageRenderPrimitive( GLcontext *ctx, GLenum prim ); + +/*********************************************************************** + * Emit primitives * + ***********************************************************************/ + +static __inline__ GLuint * savage_send_one_vertex(savageContextPtr imesa, savageVertexPtr v, GLuint * vb, GLuint start, GLuint size) +{ + GLuint j; + for (j = start ; j < size ; j++) + { + WRITE_CMD(vb, v->ui[j],GLuint); + } + return vb; +} + +static void __inline__ savage_draw_triangle( savageContextPtr imesa, + savageVertexPtr v0, + savageVertexPtr v1, + savageVertexPtr v2 ) +{ + GLuint vertsize = imesa->vertex_size; +#if SAVAGEDEBUG + GLuint *vb = savageDMAAlloc (imesa, 3 * vertsize + 1 + 8); +#else + GLuint *vb = savageDMAAlloc (imesa, 4 * vertsize + 1); +#endif + + imesa->DrawPrimitiveCmd &= + ~(SAVAGE_HW_TRIANGLE_TYPE| SAVAGE_HW_TRIANGLE_CONT); + WRITE_CMD(vb,SAVAGE_DRAW_PRIMITIVE(3, imesa->DrawPrimitiveCmd&imesa->DrawPrimitiveMask, 0),GLuint); + + vb = savage_send_one_vertex(imesa, v0, vb, 0, vertsize); + vb = savage_send_one_vertex(imesa, v1, vb, 0, vertsize); + vb = savage_send_one_vertex(imesa, v2, vb, 0, vertsize); + +#if SAVAGEDEBUG + { + GLuint x0,y0,w,h; + x0 = (GLuint)imesa->drawX; + y0 = (GLuint)imesa->drawY; + w = (GLuint)imesa->driDrawable->w; + h = (GLuint)imesa->driDrawable->h; + + (*vb) = 0x4BCC00C0; + vb++; + (*vb) = imesa->savageScreen->backOffset; + vb++; + (*vb) = imesa->savageScreen->backBitmapDesc; + vb++; + (*vb) = (y0<<16)|x0; + vb++; + (*vb) = 0x0; + vb++; + (*vb) = (h<<16)|w; + vb++; + } +#endif + savageDMACommit (imesa, vb); +} + +static __inline__ void savage_draw_point( savageContextPtr imesa, + savageVertexPtr tmp ) +{ + GLfloat sz = imesa->glCtx->Point._Size * .5; + int vertsize = imesa->vertex_size; + GLuint *vb = savageDMAAlloc (imesa, 4 * vertsize + 1); + const GLfloat x = tmp->v.x; + const GLfloat y = tmp->v.y; + + imesa->DrawPrimitiveCmd &= + ~(SAVAGE_HW_TRIANGLE_TYPE | SAVAGE_HW_TRIANGLE_CONT); + imesa->DrawPrimitiveCmd |= SAVAGE_HW_TRIANGLE_FAN; + + WRITE_CMD(vb, SAVAGE_DRAW_PRIMITIVE(4, imesa->DrawPrimitiveCmd&imesa->DrawPrimitiveMask, 0),GLuint); + + WRITE_CMD(vb, x - sz, GLfloat); + WRITE_CMD(vb, y - sz, GLfloat); + vb = savage_send_one_vertex(imesa, tmp, vb, 2, vertsize); + + WRITE_CMD(vb, x + sz, GLfloat); + WRITE_CMD(vb, y - sz, GLfloat); + vb = savage_send_one_vertex(imesa, tmp, vb, 2, vertsize); + + WRITE_CMD(vb, x + sz, GLfloat); + WRITE_CMD(vb, y + sz, GLfloat); + vb = savage_send_one_vertex(imesa, tmp, vb, 2, vertsize); + + WRITE_CMD(vb, x - sz, GLfloat); + WRITE_CMD(vb, y + sz, GLfloat); + vb = savage_send_one_vertex(imesa, tmp, vb, 2, vertsize); + + savageDMACommit (imesa, vb); +} + + +static __inline__ void savage_draw_line( savageContextPtr imesa, + savageVertexPtr v0, + savageVertexPtr v1 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = savageDMAAlloc (imesa, 4 * vertsize + 1); + GLfloat dx, dy, ix, iy; + GLfloat width = imesa->glCtx->Line._Width; + + imesa->DrawPrimitiveCmd &= + ~(SAVAGE_HW_TRIANGLE_TYPE | SAVAGE_HW_TRIANGLE_CONT); + imesa->DrawPrimitiveCmd |= SAVAGE_HW_TRIANGLE_FAN; + WRITE_CMD(vb, SAVAGE_DRAW_PRIMITIVE(4, imesa->DrawPrimitiveCmd&imesa->DrawPrimitiveMask, 0),GLuint); + + dx = v0->v.x - v1->v.x; + dy = v0->v.y - v1->v.y; + + ix = width * .5; iy = 0; + if (dx * dx > dy * dy) { + iy = ix; ix = 0; + } + + WRITE_CMD(vb, (v0->v.x - ix), GLfloat); + WRITE_CMD(vb, (v0->v.y - iy), GLfloat); + vb = savage_send_one_vertex(imesa, v0, vb, 2, vertsize); + + WRITE_CMD(vb, (v1->v.x - ix), GLfloat); + WRITE_CMD(vb, (v1->v.y - iy), GLfloat); + vb = savage_send_one_vertex(imesa, v1, vb, 2, vertsize); + + WRITE_CMD(vb, (v1->v.x + ix), GLfloat); + WRITE_CMD(vb, (v1->v.y + iy), GLfloat); + vb = savage_send_one_vertex(imesa, v1, vb, 2, vertsize); + + WRITE_CMD(vb, (v0->v.x + ix), GLfloat); + WRITE_CMD(vb, (v0->v.y + iy), GLfloat); + vb = savage_send_one_vertex(imesa, v0, vb, 2, vertsize); + + savageDMACommit (imesa, vb); +} + +static void __inline__ savage_draw_quad( savageContextPtr imesa, + savageVertexPtr v0, + savageVertexPtr v1, + savageVertexPtr v2, + savageVertexPtr v3 ) +{ + GLuint vertsize = imesa->vertex_size; + GLuint *vb = savageDMAAlloc (imesa, 6 * vertsize + 1); + + imesa->DrawPrimitiveCmd &= + ~(SAVAGE_HW_TRIANGLE_TYPE | SAVAGE_HW_TRIANGLE_CONT); + WRITE_CMD(vb, SAVAGE_DRAW_PRIMITIVE(6, imesa->DrawPrimitiveCmd&imesa->DrawPrimitiveMask, 0),GLuint); + + vb = savage_send_one_vertex(imesa, v0, vb, 0, vertsize); + vb = savage_send_one_vertex(imesa, v1, vb, 0, vertsize); + vb = savage_send_one_vertex(imesa, v3, vb, 0, vertsize); + vb = savage_send_one_vertex(imesa, v1, vb, 0, vertsize); + vb = savage_send_one_vertex(imesa, v2, vb, 0, vertsize); + vb = savage_send_one_vertex(imesa, v3, vb, 0, vertsize); + + savageDMACommit (imesa, vb); +} + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + imesa->draw_tri( imesa, a, b, c ); \ + else \ + savage_draw_triangle( imesa, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + imesa->draw_tri( imesa, a, b, d ); \ + imesa->draw_tri( imesa, b, c, d ); \ + } else \ + savage_draw_quad( imesa, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + imesa->draw_line( imesa, v0, v1 ); \ + else \ + savage_draw_line( imesa, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + imesa->draw_point( imesa, v0 ); \ + else \ + savage_draw_point( imesa, v0 ); \ +} while (0) + + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define SAVAGE_OFFSET_BIT 0x1 +#define SAVAGE_TWOSIDE_BIT 0x2 +#define SAVAGE_UNFILLED_BIT 0x4 +#define SAVAGE_FALLBACK_BIT 0x8 +#define SAVAGE_MAX_TRIFUNC 0x10 + + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[SAVAGE_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & SAVAGE_FALLBACK_BIT) +#define DO_OFFSET (IND & SAVAGE_OFFSET_BIT) +#define DO_UNFILLED (IND & SAVAGE_UNFILLED_BIT) +#define DO_TWOSIDE (IND & SAVAGE_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 savageVertex +#define TAB rast_tab + +#define DEPTH_SCALE imesa->depth_scale +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW( a ) (a > 0) +#define GET_VERTEX(e) (imesa->verts + (e * imesa->vertex_size * sizeof(int))) + +#define SAVAGE_COLOR( dst, src ) \ +do { \ + dst[0] = src[2]; \ + dst[1] = src[1]; \ + dst[2] = src[0]; \ + dst[3] = src[3]; \ +} while (0) + +#define SAVAGE_SPEC( dst, src ) \ +do { \ + dst[0] = src[2]; \ + dst[1] = src[1]; \ + dst[2] = src[0]; \ +} while (0) + +#define VERT_SET_RGBA( v, c ) SAVAGE_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) SAVAGE_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) \ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = 4/*(rmesa->vertex_size == 4 ? 3 : 4)*/; \ + GLboolean havespec = 1/*(rmesa->vertex_size == 4 ? 0 : 1)*/; \ + (void) color; (void) spec; (void) coloroffset; (void) havespec; + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) +#define RENDER_PRIMITIVE imesa->render_primitive +#define IND SAVAGE_FALLBACK_BIT +#define TAG(x) x +#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 (SAVAGE_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_TWOSIDE_BIT|SAVAGE_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_OFFSET_BIT|SAVAGE_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_TWOSIDE_BIT|SAVAGE_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_TWOSIDE_BIT|SAVAGE_OFFSET_BIT|SAVAGE_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_OFFSET_BIT|SAVAGE_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_TWOSIDE_BIT|SAVAGE_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_TWOSIDE_BIT|SAVAGE_OFFSET_BIT|SAVAGE_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_UNFILLED_BIT|SAVAGE_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_OFFSET_BIT|SAVAGE_UNFILLED_BIT|SAVAGE_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_TWOSIDE_BIT|SAVAGE_UNFILLED_BIT|SAVAGE_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SAVAGE_TWOSIDE_BIT|SAVAGE_OFFSET_BIT|SAVAGE_UNFILLED_BIT| \ + SAVAGE_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 +savage_fallback_tri( savageContextPtr imesa, + savageVertexPtr v0, + savageVertexPtr v1, + savageVertexPtr v2 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[3]; + savage_translate_vertex( ctx, v0, &v[0] ); + savage_translate_vertex( ctx, v1, &v[1] ); + savage_translate_vertex( ctx, v2, &v[2] ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); +} + + +static void +savage_fallback_line( savageContextPtr imesa, + savageVertexPtr v0, + savageVertexPtr v1 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[2]; + savage_translate_vertex( ctx, v0, &v[0] ); + savage_translate_vertex( ctx, v1, &v[1] ); + _swrast_Line( ctx, &v[0], &v[1] ); +} + + +static void +savage_fallback_point( savageContextPtr imesa, + savageVertexPtr v0 ) +{ + GLcontext *ctx = imesa->glCtx; + SWvertex v[1]; + savage_translate_vertex( ctx, v0, &v[0] ); + _swrast_Point( ctx, &v[0] ); +} + + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define VERT(x) (savageVertexPtr)(savageVerts + (x * vertsize * sizeof(int))) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + savage_draw_point( imesa, VERT(start) ) +#define RENDER_LINE( v0, v1 ) \ + savage_draw_line( imesa, VERT(v0), VERT(v1) ) +#define RENDER_TRI( v0, v1, v2 ) \ + savage_draw_triangle( imesa, VERT(v0), VERT(v1), VERT(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) \ + savage_draw_quad( imesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) +#define INIT(x) do { \ + if (0) fprintf(stderr, "%s\n", __FUNCTION__); \ + savageRenderPrimitive( ctx, x ); \ + /*SAVAGE_CONTEXT(ctx)->render_primitive = x;*/ \ +} while (0) +#undef LOCAL_VARS +#define LOCAL_VARS \ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); \ + const GLuint vertsize = imesa->vertex_size; \ + const char *savageVerts = (char *)imesa->verts; \ + 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) savage_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) savage_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + +static void savageRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + /* 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; + } +} + +static void savageRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Line( ctx, ii, jj ); +} +/* +static void savageFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + r128ContextPtr rmesa = R128_CONTEXT( ctx ); + GLuint vertsize = rmesa->vertex_size; + GLuint *vb = r128AllocDmaLow( rmesa, (n-2) * 3 * 4 * vertsize ); + GLubyte *r128verts = (GLubyte *)rmesa->verts; + const GLuint shift = rmesa->vertex_stride_shift; + const GLuint *start = (const GLuint *)VERT(elts[0]); + int i,j; + + rmesa->num_verts += (n-2) * 3; + + for (i = 2 ; i < n ; i++) { + COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) start ); + COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) VERT(elts[i-1]) ); + COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) VERT(elts[i]) ); + } +} +*/ + + + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + +#define _SAVAGE_NEW_RENDER_STATE (_DD_NEW_LINE_STIPPLE | \ + _DD_NEW_LINE_SMOOTH | \ + _DD_NEW_POINT_SMOOTH | \ + _DD_NEW_TRI_SMOOTH | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET) \ + +/* original driver didn't have DD_POINT_SMOOTH. really needed? */ +#define POINT_FALLBACK (DD_POINT_SMOOTH) +#define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH) +#define TRI_FALLBACK (DD_TRI_SMOOTH) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) + + +static void savageChooseRenderState(GLcontext *ctx) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) { + imesa->draw_point = savage_draw_point; + imesa->draw_line = savage_draw_line; + imesa->draw_tri = savage_draw_triangle; + + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= SAVAGE_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= SAVAGE_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= SAVAGE_UNFILLED_BIT; + } + + /* Hook in fallbacks for specific primitives. + */ + if (flags & (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)) { + if (flags & POINT_FALLBACK) imesa->draw_point = savage_fallback_point; + if (flags & LINE_FALLBACK) imesa->draw_line = savage_fallback_line; + if (flags & TRI_FALLBACK) imesa->draw_tri = savage_fallback_tri; + index |= SAVAGE_FALLBACK_BIT; + } + } + + if (index != imesa->RenderIndex) { + TNLcontext *tnl = TNL_CONTEXT(ctx); + 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 = savage_render_tab_verts; + tnl->Driver.Render.PrimTabElts = savage_render_tab_elts; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; + tnl->Driver.Render.ClippedPolygon = savageRenderClippedPoly/*r128FastRenderClippedPoly*/; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = savageRenderClippedLine; + tnl->Driver.Render.ClippedPolygon = savageRenderClippedPoly; + } + + imesa->RenderIndex = index; + } +} + +/**********************************************************************/ +/* Validate state at pipeline start */ +/**********************************************************************/ + +static void savageRunPipeline( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + + if (imesa->new_state) + savageDDUpdateHwState( ctx ); + + if (!imesa->Fallback && imesa->new_gl_state) { + if (imesa->new_gl_state & _SAVAGE_NEW_VERTEX_STATE) + savageChooseVertexState( ctx ); + + if (imesa->new_gl_state & _SAVAGE_NEW_RENDER_STATE) + savageChooseRenderState( ctx ); + + imesa->new_gl_state = 0; + } + + _tnl_run_pipeline( ctx ); +} + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + +static 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 +}; + +/* This is called when Mesa switches between rendering triangle + * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc), + * and lines, points and bitmaps. + * + * As the r128 uses triangles to render lines and points, it is + * necessary to turn off hardware culling when rendering these + * primitives. + */ + +static void savageRasterPrimitive( GLcontext *ctx, GLuint prim ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + + FLUSH_BATCH( imesa ); + + /* Update culling */ + if (imesa->raster_primitive != prim) + imesa->dirty |= SAVAGE_UPLOAD_CTX; + + imesa->raster_primitive = prim; +#if 0 + if (ctx->Polygon.StippleFlag && mmesa->haveHwStipple) + { + mmesa->dirty |= MGA_UPLOAD_CONTEXT; + mmesa->setup.dwgctl &= ~(0xf<<20); + if (mmesa->raster_primitive == GL_TRIANGLES) + mmesa->setup.dwgctl |= mmesa->poly_stipple; + } +#endif +} + +static void savageRenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + GLuint rprim = reduced_prim[prim]; + + imesa->render_primitive = prim; + + if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + + if (imesa->raster_primitive != rprim) { + savageRasterPrimitive( ctx, rprim ); + } +} + + +static void savageRenderStart( GLcontext *ctx ) +{ + /* Check for projective texturing. Make sure all texcoord + * pointers point to something. (fix in mesa?) + */ + savageCheckTexSizes( ctx ); + + if (!SAVAGE_CONTEXT(ctx)->Fallback) { + /* Update hardware state and get the lock */ + savageDDRenderStart( ctx ); + } +} + +static void savageRenderFinish( GLcontext *ctx ) +{ + /* Release the lock */ + savageDDRenderEnd( ctx ); + + if (SAVAGE_CONTEXT(ctx)->RenderIndex & SAVAGE_FALLBACK_BIT) + _swrast_flush( ctx ); +} + + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + +void savageFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + GLuint oldfallback = imesa->Fallback; + + if (mode) { + imesa->Fallback |= bit; + if (oldfallback == 0) { + /* the first fallback */ + LOCK_HARDWARE(SAVAGE_CONTEXT(ctx)); + FLUSH_BATCH( imesa ); + UNLOCK_HARDWARE(SAVAGE_CONTEXT(ctx)); + _swsetup_Wakeup( ctx ); + imesa->RenderIndex = ~0; + } + } + else { + imesa->Fallback &= ~bit; + if (oldfallback == bit) { + /* the last fallback */ + _swrast_flush( ctx ); + tnl->Driver.Render.Start = savageRenderStart; + tnl->Driver.Render.PrimitiveNotify = savageRenderPrimitive; + tnl->Driver.Render.Finish = savageRenderFinish; + tnl->Driver.Render.BuildVertices = savageBuildVertices; + imesa->new_gl_state |= (_SAVAGE_NEW_RENDER_STATE| + _SAVAGE_NEW_VERTEX_STATE); + } + } +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +void savageInitTriFuncs( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.RunPipeline = savageRunPipeline; + tnl->Driver.Render.Start = savageRenderStart; + tnl->Driver.Render.Finish = savageRenderFinish; + tnl->Driver.Render.PrimitiveNotify = savageRenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = savageBuildVertices; + +/* r128Fallback( ctx, 0x100000, 1 ); */ +} diff --git a/src/mesa/drivers/dri/savage/savagetris.h b/src/mesa/drivers/dri/savage/savagetris.h new file mode 100644 index 0000000000..00803e7ff3 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagetris.h @@ -0,0 +1,49 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.h,v 1.4 2001/01/08 01:07:24 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + 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 <keithw@valinux.com> + * Felix Kuehling <fxkuehl@gmx.de> + * + */ + +#ifndef __R128_TRIS_H__ +#define __R128_TRIS_H__ + +#include "mtypes.h" + +extern void savageInitTriFuncs( GLcontext *ctx ); + + +extern void savageFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +#define FALLBACK( ctx, bit, mode ) savageFallback( ctx, bit, mode ) + + +#endif /* __R128_TRIS_H__ */ diff --git a/src/mesa/drivers/dri/savage/savagevb.c b/src/mesa/drivers/dri/savage/savagevb.c new file mode 100644 index 0000000000..f0f4f4c43d --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagevb.c @@ -0,0 +1,470 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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 <keithw@valinux.com> + * Felix Kuehling <fxkuehl@gmx.de> + */ +/* $XFree86$ */ + +#include "savagecontext.h" +#include "savagevb.h" +#include "savagetris.h" +#include "savageioctl.h" +#include "savagecontext.h" +#include "savage_bci.h" + +#include "glheader.h" +#include "mtypes.h" +#include "macros.h" +#include "colormac.h" + +#include "tnl/t_context.h" +#include "swrast_setup/swrast_setup.h" +#include "swrast/swrast.h" + +#include <stdio.h> +#include <stdlib.h> + + +#define SAVAGE_TEX1_BIT 0x1 +#define SAVAGE_TEX0_BIT 0x2 +#define SAVAGE_RGBA_BIT 0x4 +#define SAVAGE_SPEC_BIT 0x8 +#define SAVAGE_FOG_BIT 0x10 +#define SAVAGE_XYZW_BIT 0x20 +#define SAVAGE_PTEX_BIT 0x40 +#define SAVAGE_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_format; +} setup_tab[SAVAGE_MAX_SETUP]; + +/* savage supports vertices without specular color, but this is not supported + * by the vbtmp. have to check if/how tiny vertices work. */ +#define TINY_VERTEX_FORMAT 0 +#define NOTEX_VERTEX_FORMAT (SAVAGE_HW_NO_UV0|SAVAGE_HW_NO_UV1) +#define TEX0_VERTEX_FORMAT (SAVAGE_HW_NO_UV1) +#define TEX1_VERTEX_FORMAT (0) +#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 & SAVAGE_XYZW_BIT) +#define DO_RGBA (IND & SAVAGE_RGBA_BIT) +#define DO_SPEC (IND & SAVAGE_SPEC_BIT) +#define DO_FOG (IND & SAVAGE_FOG_BIT) +#define DO_TEX0 (IND & SAVAGE_TEX0_BIT) +#define DO_TEX1 (IND & SAVAGE_TEX1_BIT) +#define DO_TEX2 0 +#define DO_TEX3 0 +#define DO_PTEX (IND & SAVAGE_PTEX_BIT) + + +#define VERTEX savageVertex +#define LOCALVARS savageContextPtr imesa = SAVAGE_CONTEXT(ctx); +#define GET_VIEWPORT_MAT() imesa->hw_viewport +#define GET_TEXSOURCE(n) n +#define GET_VERTEX_FORMAT() (imesa->DrawPrimitiveCmd & \ + (SAVAGE_HW_NO_UV0|SAVAGE_HW_NO_UV1)) +#define GET_VERTEX_STORE() imesa->verts +#define GET_VERTEX_SIZE() (imesa->vertex_size * sizeof(int)) + +#define HAVE_HW_VIEWPORT 0 +#define HAVE_HW_DIVIDE 0 +#define HAVE_RGBA_COLOR 0 +#define HAVE_TINY_VERTICES 0 +#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 \ + const GLfloat dx = - imesa->drawX - SUBPIXEL_X; \ + const GLfloat dy = (imesa->driDrawable->h + \ + imesa->drawY + SUBPIXEL_Y); \ + const GLfloat sz = 1.0 / imesa->depth_scale + +#define UNVIEWPORT_X(x) x + dx; +#define UNVIEWPORT_Y(y) - y + dy; +#define UNVIEWPORT_Z(z) z * sz; + +#define PTEX_FALLBACK() (void)imesa, FALLBACK(ctx, SAVAGE_FALLBACK_TEXTURE, 1) + + +#define INTERP_VERTEX (void)imesa, setup_tab[SAVAGE_CONTEXT(ctx)->SetupIndex].interp +#define COPY_PV_VERTEX (void)imesa, setup_tab[SAVAGE_CONTEXT(ctx)->SetupIndex].copy_pv + + +/*********************************************************************** + * Generate pv-copying and translation functions * + ***********************************************************************/ + +#define TAG(x) savage_##x +#include "tnl_dd/t_dd_vb.c" + +/*********************************************************************** + * Generate vertex emit and interp functions * + ***********************************************************************/ + + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT) +#define TAG(x) x##_wg +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_SPEC_BIT) +#define TAG(x) x##_wgs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_TEX0_BIT) +#define TAG(x) x##_wgt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_TEX0_BIT|SAVAGE_TEX1_BIT) +#define TAG(x) x##_wgt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_TEX0_BIT|SAVAGE_PTEX_BIT) +#define TAG(x) x##_wgpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_SPEC_BIT|SAVAGE_TEX0_BIT) +#define TAG(x) x##_wgst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_SPEC_BIT|SAVAGE_TEX0_BIT|SAVAGE_TEX1_BIT) +#define TAG(x) x##_wgst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_SPEC_BIT|SAVAGE_TEX0_BIT|SAVAGE_PTEX_BIT) +#define TAG(x) x##_wgspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT) +#define TAG(x) x##_wgf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_SPEC_BIT) +#define TAG(x) x##_wgfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_TEX0_BIT) +#define TAG(x) x##_wgft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_TEX0_BIT|SAVAGE_TEX1_BIT) +#define TAG(x) x##_wgft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_TEX0_BIT|SAVAGE_PTEX_BIT) +#define TAG(x) x##_wgfpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_SPEC_BIT|SAVAGE_TEX0_BIT) +#define TAG(x) x##_wgfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_SPEC_BIT|SAVAGE_TEX0_BIT|SAVAGE_TEX1_BIT) +#define TAG(x) x##_wgfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_SPEC_BIT|SAVAGE_TEX0_BIT|SAVAGE_PTEX_BIT) +#define TAG(x) x##_wgfspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_TEX0_BIT) +#define TAG(x) x##_t0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_TEX0_BIT|SAVAGE_TEX1_BIT) +#define TAG(x) x##_t0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_FOG_BIT) +#define TAG(x) x##_f +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_FOG_BIT|SAVAGE_TEX0_BIT) +#define TAG(x) x##_ft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_FOG_BIT|SAVAGE_TEX0_BIT|SAVAGE_TEX1_BIT) +#define TAG(x) x##_ft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT) +#define TAG(x) x##_g +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_SPEC_BIT) +#define TAG(x) x##_gs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_TEX0_BIT) +#define TAG(x) x##_gt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_TEX0_BIT|SAVAGE_TEX1_BIT) +#define TAG(x) x##_gt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_SPEC_BIT|SAVAGE_TEX0_BIT) +#define TAG(x) x##_gst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_SPEC_BIT|SAVAGE_TEX0_BIT|SAVAGE_TEX1_BIT) +#define TAG(x) x##_gst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT) +#define TAG(x) x##_gf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_SPEC_BIT) +#define TAG(x) x##_gfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_TEX0_BIT) +#define TAG(x) x##_gft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_TEX0_BIT|SAVAGE_TEX1_BIT) +#define TAG(x) x##_gft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_SPEC_BIT|SAVAGE_TEX0_BIT) +#define TAG(x) x##_gfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SAVAGE_RGBA_BIT|SAVAGE_FOG_BIT|SAVAGE_SPEC_BIT|SAVAGE_TEX0_BIT|SAVAGE_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 savagePrintSetupFlags(char *msg, GLuint flags ) +{ + fprintf(stderr, "%s: %d %s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & SAVAGE_XYZW_BIT) ? " xyzw," : "", + (flags & SAVAGE_RGBA_BIT) ? " rgba," : "", + (flags & SAVAGE_SPEC_BIT) ? " spec," : "", + (flags & SAVAGE_FOG_BIT) ? " fog," : "", + (flags & SAVAGE_TEX0_BIT) ? " tex-0," : "", + (flags & SAVAGE_TEX1_BIT) ? " tex-1," : ""); +} + + +void savageCheckTexSizes( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + /*fprintf(stderr, "%s\n", __FUNCTION__);*/ + + if (!setup_tab[imesa->SetupIndex].check_tex_sizes(ctx)) { + imesa->SetupIndex |= SAVAGE_PTEX_BIT; + imesa->SetupNewInputs = ~0; + + 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 savageBuildVertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + GLuint stride = imesa->vertex_size * sizeof(int); + GLubyte *v = ((GLubyte *)imesa->verts + (start * stride)); + + newinputs |= imesa->SetupNewInputs; + imesa->SetupNewInputs = 0; + + if (!newinputs) + return; + + if (newinputs & VERT_BIT_POS) { + setup_tab[imesa->SetupIndex].emit( ctx, start, count, v, stride ); + } else { + GLuint ind = 0; + + if (newinputs & VERT_BIT_COLOR0) + ind |= SAVAGE_RGBA_BIT; + + if (newinputs & VERT_BIT_COLOR1) + ind |= SAVAGE_SPEC_BIT; + + if (newinputs & VERT_BIT_TEX0) + ind |= SAVAGE_TEX0_BIT; + + if (newinputs & VERT_BIT_TEX1) + ind |= SAVAGE_TEX0_BIT|SAVAGE_TEX1_BIT; + + if (newinputs & VERT_BIT_FOG) + ind |= SAVAGE_FOG_BIT; + + if (imesa->SetupIndex & SAVAGE_PTEX_BIT) + ind = ~0; + + ind &= imesa->SetupIndex; + + if (ind) { + setup_tab[ind].emit( ctx, start, count, v, stride ); + } + } +} + + +void savageChooseVertexState( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint ind = SAVAGE_XYZW_BIT|SAVAGE_RGBA_BIT; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + ind |= SAVAGE_SPEC_BIT; + + if (ctx->Fog.Enabled) + ind |= SAVAGE_FOG_BIT; + + if (ctx->Texture._EnabledUnits & 0x2) { + if (ctx->Texture._EnabledUnits & 0x1) { + ind |= SAVAGE_TEX1_BIT|SAVAGE_TEX0_BIT; + } + else { + ind |= SAVAGE_TEX0_BIT; + } + } + else if (ctx->Texture._EnabledUnits & 0x1) { + ind |= SAVAGE_TEX0_BIT; + } + + imesa->SetupIndex = ind; + + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = savage_interp_extras; + tnl->Driver.Render.CopyPV = savage_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 != GET_VERTEX_FORMAT()) { + imesa->DrawPrimitiveCmd = setup_tab[ind].vertex_format; + imesa->vertex_size = setup_tab[ind].vertex_size; + } +} + + + +void savageInitVB( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + + imesa->verts = (GLubyte *)ALIGN_MALLOC(size * sizeof(savageVertex), 32); + + { + static int firsttime = 1; + if (firsttime) { + init_setup_tab(); + firsttime = 0; + } + } + + imesa->DrawPrimitiveCmd = setup_tab[0].vertex_format; + imesa->vertex_size = setup_tab[0].vertex_size; + + if (imesa->savageScreen->chipset >= S3_SAVAGE4) + imesa->DrawPrimitiveMask = ~0; + else + imesa->DrawPrimitiveMask = ~SAVAGE_HW_NO_UV1; +} + + +void savageFreeVB( GLcontext *ctx ) +{ + savageContextPtr imesa = SAVAGE_CONTEXT(ctx); + if (imesa->verts) { + ALIGN_FREE(imesa->verts); + imesa->verts = 0; + } +} + diff --git a/src/mesa/drivers/dri/savage/savagevb.h b/src/mesa/drivers/dri/savage/savagevb.h new file mode 100644 index 0000000000..9ee2bd9cc7 --- /dev/null +++ b/src/mesa/drivers/dri/savage/savagevb.h @@ -0,0 +1,62 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.h,v 1.6 2001/04/10 16:07:51 dawes Exp $ */ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * 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 + * VA LINUX SYSTEMS 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 <keithw@valinux.com> + * Felix Kuehling <fxkuehl@gmx.de> + */ + +#ifndef SAVAGEVB_INC +#define SAVAGEVB_INC + +#include "mtypes.h" +#include "savagecontext.h" +#include "swrast/swrast.h" + +#define _SAVAGE_NEW_VERTEX_STATE (_NEW_TEXTURE | \ + _DD_NEW_SEPARATE_SPECULAR | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _NEW_FOG) + + +extern void savageChooseVertexState( GLcontext *ctx ); +extern void savageCheckTexSizes( GLcontext *ctx ); +extern void savageBuildVertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ); + +extern void savagePrintSetupFlags(char *msg, GLuint flags ); + +extern void savageInitVB( GLcontext *ctx ); +extern void savageFreeVB( GLcontext *ctx ); + +extern void savage_translate_vertex(GLcontext *ctx, + const savageVertex *src, + SWvertex *dst); + +extern void savage_print_vertex( GLcontext *ctx, const savageVertex *v ); + +#endif |