summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/sis/sis_state.c
diff options
context:
space:
mode:
authorAlan Hourihane <[email protected]>2003-09-30 11:13:31 +0000
committerAlan Hourihane <[email protected]>2003-09-30 11:13:31 +0000
commit0f2e1869263ef04b3bc47d9817278a555201bda8 (patch)
treedcf362a09fc17d3bd37e61b9432da04ea0783e5b /src/mesa/drivers/dri/sis/sis_state.c
parent525dda4f2689469bd3179eb0ee21fd7e04413a1c (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.c918
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;
+}