diff options
author | Alan Hourihane <[email protected]> | 2003-09-30 11:13:31 +0000 |
---|---|---|
committer | Alan Hourihane <[email protected]> | 2003-09-30 11:13:31 +0000 |
commit | 0f2e1869263ef04b3bc47d9817278a555201bda8 (patch) | |
tree | dcf362a09fc17d3bd37e61b9432da04ea0783e5b /src/mesa/drivers/dri/sis/sis_state.c | |
parent | 525dda4f2689469bd3179eb0ee21fd7e04413a1c (diff) |
add the SiS driver - no kernel driver yet
(build tested, but not physically tested)
Diffstat (limited to 'src/mesa/drivers/dri/sis/sis_state.c')
-rw-r--r-- | src/mesa/drivers/dri/sis/sis_state.c | 918 |
1 files changed, 918 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/sis/sis_state.c b/src/mesa/drivers/dri/sis/sis_state.c new file mode 100644 index 00000000000..9d093595a1c --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_state.c @@ -0,0 +1,918 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin <[email protected]> + * Eric Anholt <[email protected]> + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_tris.h" +#include "sis_lock.h" +#include "sis_tex.h" + +#include "context.h" +#include "enums.h" +#include "colormac.h" +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + +/* ============================================================= + * Alpha blending + */ + +static void +sisDDAlphaFunc( GLcontext * ctx, GLenum func, GLfloat ref ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + GLubyte refbyte; + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + CLAMPED_FLOAT_TO_UBYTE(refbyte, ref); + current->hwAlpha = refbyte << 16; + + /* Alpha Test function */ + switch (func) + { + case GL_NEVER: + current->hwAlpha |= SiS_ALPHA_NEVER; + break; + case GL_LESS: + current->hwAlpha |= SiS_ALPHA_LESS; + break; + case GL_EQUAL: + current->hwAlpha |= SiS_ALPHA_EQUAL; + break; + case GL_LEQUAL: + current->hwAlpha |= SiS_ALPHA_LEQUAL; + break; + case GL_GREATER: + current->hwAlpha |= SiS_ALPHA_GREATER; + break; + case GL_NOTEQUAL: + current->hwAlpha |= SiS_ALPHA_NOTEQUAL; + break; + case GL_GEQUAL: + current->hwAlpha |= SiS_ALPHA_GEQUAL; + break; + case GL_ALWAYS: + current->hwAlpha |= SiS_ALPHA_ALWAYS; + break; + } + + prev->hwAlpha = current->hwAlpha; + smesa->GlobalFlag |= GFLAG_ALPHASETTING; +} + +static void +sisDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + /* TODO: in ICD, if no blend, it will reset these value */ + /* blending enable */ + current->hwDstSrcBlend = 0x10000; /* Default destination alpha */ + + switch (dfactor) + { + case GL_ZERO: + current->hwDstSrcBlend |= SiS_D_ZERO; + break; + case GL_ONE: + current->hwDstSrcBlend |= SiS_D_ONE; + break; + case GL_SRC_COLOR: + current->hwDstSrcBlend |= SiS_D_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + current->hwDstSrcBlend |= SiS_D_ONE_MINUS_SRC_COLOR; + break; + case GL_SRC_ALPHA: + current->hwDstSrcBlend |= SiS_D_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + current->hwDstSrcBlend |= SiS_D_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + current->hwDstSrcBlend |= SiS_D_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + current->hwDstSrcBlend |= SiS_D_ONE_MINUS_DST_ALPHA; + break; + } + + switch (sfactor) + { + case GL_ZERO: + current->hwDstSrcBlend |= SiS_S_ZERO; + break; + case GL_ONE: + current->hwDstSrcBlend |= SiS_S_ONE; + break; + case GL_SRC_ALPHA: + current->hwDstSrcBlend |= SiS_S_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + current->hwDstSrcBlend |= SiS_S_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + current->hwDstSrcBlend |= SiS_S_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + current->hwDstSrcBlend |= SiS_S_ONE_MINUS_DST_ALPHA; + break; + case GL_DST_COLOR: + current->hwDstSrcBlend |= SiS_S_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + current->hwDstSrcBlend |= SiS_S_ONE_MINUS_DST_COLOR; + break; + case GL_SRC_ALPHA_SATURATE: + current->hwDstSrcBlend |= SiS_S_SRC_ALPHA_SATURATE; + break; + } + + if (current->hwDstSrcBlend != prev->hwDstSrcBlend) { + prev->hwDstSrcBlend = current->hwDstSrcBlend; + smesa->GlobalFlag |= GFLAG_DSTBLEND; + } +} + +/* ============================================================= + * Depth testing + */ + +static void +sisDDDepthFunc( GLcontext * ctx, GLenum func ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + current->hwZ &= ~MASK_ZTestMode; + switch (func) + { + case GL_LESS: + current->hwZ |= SiS_Z_COMP_S_LT_B; + break; + case GL_GEQUAL: + current->hwZ |= SiS_Z_COMP_S_GE_B; + break; + case GL_LEQUAL: + current->hwZ |= SiS_Z_COMP_S_LE_B; + break; + case GL_GREATER: + current->hwZ |= SiS_Z_COMP_S_GT_B; + break; + case GL_NOTEQUAL: + current->hwZ |= SiS_Z_COMP_S_NE_B; + break; + case GL_EQUAL: + current->hwZ |= SiS_Z_COMP_S_EQ_B; + break; + case GL_ALWAYS: + current->hwZ |= SiS_Z_COMP_ALWAYS; + break; + case GL_NEVER: + current->hwZ |= SiS_Z_COMP_NEVER; + break; + } + + if (current->hwZ != prev->hwZ) { + prev->hwZ = current->hwZ; + smesa->GlobalFlag |= GFLAG_ZSETTING; + } +} + +void +sisDDDepthMask( GLcontext * ctx, GLboolean flag ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if (!ctx->Depth.Test) + flag = GL_FALSE; + + if (ctx->Visual.stencilBits) { + if (flag || (ctx->Stencil.WriteMask[0] != 0)) { + current->hwCapEnable |= MASK_ZWriteEnable; + if (flag && (ctx->Stencil.WriteMask[0] == 0xff)) { + current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable; + } else { + current->hwCapEnable2 |= MASK_ZMaskWriteEnable; + current->hwZMask = (ctx->Stencil.WriteMask[0] << 24) | + ((flag) ? 0x00ffffff : 0); + + if (current->hwZMask ^ prev->hwZMask) { + prev->hwZMask = current->hwZMask; + smesa->GlobalFlag |= GFLAG_ZSETTING; + } + } + } else { + current->hwCapEnable &= ~MASK_ZWriteEnable; + } + } else { + if (flag) { + current->hwCapEnable |= MASK_ZWriteEnable; + current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable; + } else { + current->hwCapEnable &= ~MASK_ZWriteEnable; + } + } +} + +/* ============================================================= + * Clipping + */ + +void +sisUpdateClipping( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + GLint x1, y1, x2, y2; + + x1 = 0; + y1 = 0; + x2 = smesa->width - 1; + y2 = smesa->height - 1; + + if (ctx->Scissor.Enabled) { + if (ctx->Scissor.X > x1) + x1 = ctx->Scissor.X; + if (ctx->Scissor.Y > y1) + y1 = ctx->Scissor.Y; + if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2) + x2 = ctx->Scissor.X + ctx->Scissor.Width - 1; + if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < y2) + y2 = ctx->Scissor.Y + ctx->Scissor.Height - 1; + } + + y1 = Y_FLIP(y1); + y2 = Y_FLIP(y2); + + current->clipTopBottom = (y2 << 13) | y1; + current->clipLeftRight = (x1 << 13) | x2; + + if ((current->clipTopBottom ^ prev->clipTopBottom) || + (current->clipLeftRight ^ prev->clipLeftRight)) + { + prev->clipTopBottom = current->clipTopBottom; + prev->clipLeftRight = current->clipLeftRight; + smesa->GlobalFlag |= GFLAG_CLIPPING; + } +} + +static void +sisDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) +{ + if (ctx->Scissor.Enabled) + sisUpdateClipping( ctx ); +} + +/* ============================================================= + * Culling + */ + +static void +sisUpdateCull( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + GLint cullflag, frontface; + + cullflag = ctx->Polygon.CullFaceMode; + frontface = ctx->Polygon.FrontFace; + + smesa->AGPParseSet &= ~(MASK_PsCullDirection_CCW); + smesa->dwPrimitiveSet &= ~(MASK_CullDirection); + + if((cullflag == GL_FRONT && frontface == GL_CCW) || + (cullflag == GL_BACK && frontface == GL_CW)) + { + smesa->AGPParseSet |= MASK_PsCullDirection_CCW; + smesa->dwPrimitiveSet |= OP_3D_CullDirection_CCW; + } +} + + +static void +sisDDCullFace( GLcontext *ctx, GLenum mode ) +{ + sisUpdateCull( ctx ); +} + +static void +sisDDFrontFace( GLcontext *ctx, GLenum mode ) +{ + sisUpdateCull( ctx ); +} + +/* ============================================================= + * Masks + */ + +static void sisDDColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if (r && g && b && ((ctx->Visual.alphaBits == 0) || a)) { + current->hwCapEnable2 &= ~(MASK_AlphaMaskWriteEnable | + MASK_ColorMaskWriteEnable); + } else { + current->hwCapEnable2 |= (MASK_AlphaMaskWriteEnable | + MASK_ColorMaskWriteEnable); + + current->hwDstMask = (r) ? GET_RMASK(smesa) : 0 | + (g) ? GET_GMASK(smesa) : 0 | + (b) ? GET_BMASK(smesa) : 0 | + (a) ? GET_AMASK(smesa) : 0; + } + + if (current->hwDstMask != prev->hwDstMask) { + prev->hwDstMask = current->hwDstMask; + smesa->GlobalFlag |= GFLAG_DESTSETTING; + } +} + +/* ============================================================= + * Rendering attributes + */ + +static void sisDDShadeModel( GLcontext *ctx, GLenum mode ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + /* Signal to sisRasterPrimitive to recalculate dwPrimitiveSet */ + smesa->hw_primitive = -1; +} + +/* ============================================================= + * Window position + */ + +/* ============================================================= + * Viewport + */ + +static void sisCalcViewport( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = smesa->hw_viewport; + + /* See also sis_translate_vertex. + */ + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + m[MAT_SY] = - v[MAT_SY]; + m[MAT_TY] = - v[MAT_TY] + smesa->driDrawable->h + SUBPIXEL_Y; + m[MAT_SZ] = v[MAT_SZ] * smesa->depth_scale; + m[MAT_TZ] = v[MAT_TZ] * smesa->depth_scale; +} + +static void sisDDViewport( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + sisCalcViewport( ctx ); +} + +static void sisDDDepthRange( GLcontext *ctx, + GLclampd nearval, GLclampd farval ) +{ + sisCalcViewport( ctx ); +} + +/* ============================================================= + * Miscellaneous + */ + +static void +sisDDLogicOpCode( GLcontext *ctx, GLenum opcode ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if (!ctx->Color.ColorLogicOpEnabled) + return; + + current->hwDstSet &= ~MASK_ROP2; + switch (opcode) + { + case GL_CLEAR: + current->hwDstSet |= LOP_CLEAR; + break; + case GL_SET: + current->hwDstSet |= LOP_SET; + break; + case GL_COPY: + current->hwDstSet |= LOP_COPY; + break; + case GL_COPY_INVERTED: + current->hwDstSet |= LOP_COPY_INVERTED; + break; + case GL_NOOP: + current->hwDstSet |= LOP_NOOP; + break; + case GL_INVERT: + current->hwDstSet |= LOP_INVERT; + break; + case GL_AND: + current->hwDstSet |= LOP_AND; + break; + case GL_NAND: + current->hwDstSet |= LOP_NAND; + break; + case GL_OR: + current->hwDstSet |= LOP_OR; + break; + case GL_NOR: + current->hwDstSet |= LOP_NOR; + break; + case GL_XOR: + current->hwDstSet |= LOP_XOR; + break; + case GL_EQUIV: + current->hwDstSet |= LOP_EQUIV; + break; + case GL_AND_REVERSE: + current->hwDstSet |= LOP_AND_REVERSE; + break; + case GL_AND_INVERTED: + current->hwDstSet |= LOP_AND_INVERTED; + break; + case GL_OR_REVERSE: + current->hwDstSet |= LOP_OR_REVERSE; + break; + case GL_OR_INVERTED: + current->hwDstSet |= LOP_OR_INVERTED; + break; + } + + if (current->hwDstSet ^ prev->hwDstSet) { + prev->hwDstSet = current->hwDstSet; + smesa->GlobalFlag |= GFLAG_DESTSETTING; + } +} + +void sisDDDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + /* + * _DrawDestMask is easier to cope with than <mode>. + */ + switch ( ctx->Color._DrawDestMask ) { + case FRONT_LEFT_BIT: + case BACK_LEFT_BIT: + FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + default: + /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ + FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + + /* We want to update the s/w rast state too so that sisDDSetBuffer() + * gets called. + */ + _swrast_DrawBuffer(ctx, mode); + + current->hwOffsetDest = (smesa->drawOffset) >> 1; + current->hwDstSet &= ~MASK_DstBufferPitch; + current->hwDstSet |= smesa->drawPitch >> 2; + + if (current->hwDstSet != prev->hwDstSet) { + prev->hwDstSet = current->hwDstSet; + smesa->GlobalFlag |= GFLAG_DESTSETTING; + } + + if (current->hwOffsetDest != prev->hwOffsetDest) { + prev->hwOffsetDest = current->hwOffsetDest; + smesa->GlobalFlag |= GFLAG_DESTSETTING; + } +} + +static void +sisDDHint( GLcontext *ctx, GLenum target, GLenum mode ) +{ + + switch (target) { + case GL_FOG_HINT: + /* Update fog mode setting */ + sisDDFogfv(ctx, GL_FOG_MODE, NULL); + break; + } + +} + +/* ============================================================= + * Polygon stipple + */ + +/* ============================================================= + * Render mode + */ + +/* ============================================================= + * State enable/disable + */ + +static void +sisDDEnable( GLcontext * ctx, GLenum cap, GLboolean state ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *current = &smesa->current; + + switch (cap) + { + case GL_ALPHA_TEST: + if (state) + current->hwCapEnable |= MASK_AlphaTestEnable; + else + current->hwCapEnable &= ~MASK_AlphaTestEnable; + break; + case GL_BLEND: + /* TODO: */ + if (state) + /* if (state & !ctx->Color.ColorLogicOpEnabled) */ + current->hwCapEnable |= MASK_BlendEnable; + else + current->hwCapEnable &= ~MASK_BlendEnable; + break; + case GL_CULL_FACE: + if (state) + current->hwCapEnable |= MASK_CullEnable; + else + current->hwCapEnable &= ~MASK_CullEnable; + break; + case GL_DEPTH_TEST: + if (state && smesa->depthbuffer) + current->hwCapEnable |= MASK_ZTestEnable; + else + current->hwCapEnable &= ~MASK_ZTestEnable; + sisDDDepthMask( ctx, ctx->Depth.Mask ); + break; + case GL_DITHER: + if (state) + current->hwCapEnable |= MASK_DitherEnable; + else + current->hwCapEnable &= ~MASK_DitherEnable; + break; + case GL_FOG: + if (state) + current->hwCapEnable |= MASK_FogEnable; + else + current->hwCapEnable &= ~MASK_FogEnable; + break; + case GL_COLOR_LOGIC_OP: + if (state) + sisDDLogicOpCode( ctx, ctx->Color.LogicOp ); + else + sisDDLogicOpCode( ctx, GL_COPY ); + break; + case GL_SCISSOR_TEST: + sisUpdateClipping( ctx ); + break; + case GL_STENCIL_TEST: + if (state) { + if (smesa->zFormat != SiS_ZFORMAT_S8Z24) + FALLBACK(smesa, SIS_FALLBACK_STENCIL, 1); + else + current->hwCapEnable |= (MASK_StencilTestEnable | + MASK_StencilWriteEnable); + } else { + FALLBACK(smesa, SIS_FALLBACK_STENCIL, 0); + current->hwCapEnable &= ~(MASK_StencilTestEnable | + MASK_StencilWriteEnable); + } + break; + } +} + +/* ============================================================= + * Pixel functions + */ + +static void +sisDDDrawPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + LOCK_HARDWARE(); + _swrast_DrawPixels( ctx, x, y, width, height, format, type, unpack, pixels ); + UNLOCK_HARDWARE(); +} + +static void +sisDDReadPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *pixels ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + LOCK_HARDWARE(); + _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, + pixels); + UNLOCK_HARDWARE(); +} + +static void +sisDDBitmap( GLcontext *ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + LOCK_HARDWARE(); + _swrast_Bitmap( ctx, px, py, width, height, unpack, bitmap ); + UNLOCK_HARDWARE(); +} + +/* ============================================================= + * State initialization, management + */ + +/* Called before beginning of rendering. */ +void +sisUpdateHWState( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if (smesa->NewGLState & _NEW_TEXTURE) + sisUpdateTextureState( ctx ); + + /* enable setting 1 */ + if (current->hwCapEnable ^ prev->hwCapEnable) { + prev->hwCapEnable = current->hwCapEnable; + smesa->GlobalFlag |= GFLAG_ENABLESETTING; + } + + /* enable setting 2 */ + if (current->hwCapEnable2 ^ prev->hwCapEnable2) { + prev->hwCapEnable2 = current->hwCapEnable2; + smesa->GlobalFlag |= GFLAG_ENABLESETTING2; + } + + /* TODO: if fog disable, don't check */ + if (current->hwCapEnable & MASK_FogEnable) { + /* fog setting */ + if (current->hwFog != prev->hwFog) { + prev->hwFog = current->hwFog; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + if (current->hwFogFar != prev->hwFogFar) { + prev->hwFogFar = current->hwFogFar; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + if (current->hwFogInverse != prev->hwFogInverse) { + prev->hwFogInverse = current->hwFogInverse; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + if (current->hwFogDensity != prev->hwFogDensity) { + prev->hwFogDensity = current->hwFogDensity; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + } + + if (smesa->GlobalFlag & GFLAG_RENDER_STATES) + sis_update_render_state( smesa ); + + if (smesa->GlobalFlag & GFLAG_TEXTURE_STATES) + sis_update_texture_state( smesa ); +} + +static void +sisDDInvalidateState( GLcontext *ctx, GLuint new_state ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + smesa->NewGLState |= new_state; +} + +/* Initialize the context's hardware state. + */ +void sisDDInitState( sisContextPtr smesa ) +{ + __GLSiSHardware *current = &smesa->current; + __GLSiSHardware *prev = &(smesa->prev); + GLcontext *ctx = smesa->glCtx; + + /* add Texture Perspective Enable */ + prev->hwCapEnable = MASK_FogPerspectiveEnable | MASK_TextureCacheEnable | + MASK_TexturePerspectiveEnable | MASK_DitherEnable; + /*| MASK_SpecularEnable*/ + + /* + prev->hwCapEnable2 = 0x00aa0080; + */ + /* if multi-texture enabled, disable Z pre-test */ + prev->hwCapEnable2 = MASK_TextureMipmapBiasEnable; + + /* Z test mode is LESS */ + prev->hwZ = SiS_Z_COMP_S_LT_B; + + /* Depth mask */ + prev->hwZMask = 0xffffffff; + + /* Alpha test mode is ALWAYS, alpha ref value is 0 */ + prev->hwAlpha = SiS_ALPHA_ALWAYS; + + /* ROP2 is COPYPEN */ + prev->hwDstSet = LOP_COPY; + + /* color mask */ + prev->hwDstMask = 0xffffffff; + + /* LinePattern is 0, Repeat Factor is 0 */ + prev->hwLinePattern = 0x00008000; + + /* Src blend is BLEND_ONE, Dst blend is D3DBLEND_ZERO */ + prev->hwDstSrcBlend = SiS_S_ONE | SiS_D_ZERO; + + /* Stenciling disabled, function ALWAYS, ref value zero, mask all ones */ + prev->hwStSetting = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS | 0xff; + /* Op is KEEP for all three operations */ + prev->hwStSetting2 = SiS_SFAIL_KEEP | SiS_SPASS_ZFAIL_KEEP | + SiS_SPASS_ZPASS_KEEP; + + /* Texture mapping mode is Tile */ +#if 0 + prev->texture[0].hwTextureSet = 0x00030000; +#endif + /* Magnified & minified texture filter is NEAREST */ +#if 0 + prev->texture[0].hwTextureMip = 0; +#endif + + /* Texture Blending seeting */ + prev->hwTexBlendClr0 = L_REPLACE__RGB_STAGE0; + prev->hwTexBlendClr1 = 0x294B4000; + prev->hwTexBlendAlpha0 = 0x333A0000; + prev->hwTexBlendAlpha1 = 0x333A0000; + + switch (smesa->bytesPerPixel) + { + case 2: + prev->hwDstSet |= DST_FORMAT_RGB_565; + break; + case 4: + prev->hwDstSet |= DST_FORMAT_ARGB_8888; + break; + } + + switch (ctx->Visual.depthBits) + { + case 0: + prev->hwCapEnable &= ~MASK_ZWriteEnable; + case 16: + smesa->zFormat = SiS_ZFORMAT_Z16; + prev->hwCapEnable |= MASK_ZWriteEnable; + smesa->depth_scale = 1.0 / (GLfloat)0xffff; + break; + case 32: + smesa->zFormat = SiS_ZFORMAT_Z32; + prev->hwCapEnable |= MASK_ZWriteEnable; + smesa->depth_scale = 1.0 / (GLfloat)0xffffffff; + break; + case 24: + assert (ctx->Visual.stencilBits); + smesa->zFormat = SiS_ZFORMAT_S8Z24; + prev->hwCapEnable |= MASK_StencilBufferEnable; + prev->hwCapEnable |= MASK_ZWriteEnable; + smesa->depth_scale = 1.0 / (GLfloat)0xffffff; + break; + } + + prev->hwZ |= smesa->zFormat; + + /* TODO: need to clear cache? */ + smesa->clearTexCache = GL_TRUE; + + smesa->clearColorPattern = 0; + + smesa->AGPParseSet = MASK_PsTexture1FromB; + smesa->dwPrimitiveSet = OP_3D_Texture1FromB | OP_3D_TextureBumpFromC; + + sisUpdateZStencilPattern( smesa, 1.0, 0 ); + sisUpdateCull( ctx ); + + memcpy( current, prev, sizeof (__GLSiSHardware) ); + + /* Set initial fog settings. Start and end are the same case. */ + sisDDFogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); + sisDDFogfv( ctx, GL_FOG_END, &ctx->Fog.End ); + sisDDFogfv( ctx, GL_FOG_MODE, NULL ); +} + +/* Initialize the driver's state functions. + */ +void sisDDInitStateFuncs( GLcontext *ctx ) +{ + ctx->Driver.UpdateState = sisDDInvalidateState; + + ctx->Driver.Clear = sisDDClear; + ctx->Driver.ClearColor = sisDDClearColor; + ctx->Driver.ClearDepth = sisDDClearDepth; + ctx->Driver.ClearStencil = sisDDClearStencil; + + ctx->Driver.AlphaFunc = sisDDAlphaFunc; + ctx->Driver.Bitmap = sisDDBitmap; + ctx->Driver.BlendFunc = sisDDBlendFunc; + ctx->Driver.ColorMask = sisDDColorMask; + ctx->Driver.CullFace = sisDDCullFace; + ctx->Driver.DepthMask = sisDDDepthMask; + ctx->Driver.DepthFunc = sisDDDepthFunc; + ctx->Driver.DepthRange = sisDDDepthRange; + ctx->Driver.DrawBuffer = sisDDDrawBuffer; + ctx->Driver.DrawPixels = sisDDDrawPixels; + ctx->Driver.Enable = sisDDEnable; + ctx->Driver.FrontFace = sisDDFrontFace; + ctx->Driver.Fogfv = sisDDFogfv; + ctx->Driver.Hint = sisDDHint; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LogicOpcode = sisDDLogicOpCode; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.PolygonStipple = NULL; + ctx->Driver.ReadBuffer = NULL; + ctx->Driver.ReadPixels = sisDDReadPixels; + ctx->Driver.RenderMode = NULL; + ctx->Driver.Scissor = sisDDScissor; + ctx->Driver.ShadeModel = sisDDShadeModel; + ctx->Driver.Viewport = sisDDViewport; + + /* Pixel path fallbacks. + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + + /* 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; +} |