diff options
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 | 
