summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/gamma/gamma_state.c
diff options
context:
space:
mode:
authorAlan Hourihane <[email protected]>2003-09-30 11:28:16 +0000
committerAlan Hourihane <[email protected]>2003-09-30 11:28:16 +0000
commite508f7f08e6fa4292136a377150fc058c041fbc0 (patch)
treea012bb2a36fc4858d03e3b6af9a6fe714000f10b /src/mesa/drivers/dri/gamma/gamma_state.c
parent0f2e1869263ef04b3bc47d9817278a555201bda8 (diff)
add gamma driver - no kernel driver yet
(build tested, not physically tested)
Diffstat (limited to 'src/mesa/drivers/dri/gamma/gamma_state.c')
-rw-r--r--src/mesa/drivers/dri/gamma/gamma_state.c1734
1 files changed, 1734 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/gamma/gamma_state.c b/src/mesa/drivers/dri/gamma/gamma_state.c
new file mode 100644
index 00000000000..8a767206782
--- /dev/null
+++ b/src/mesa/drivers/dri/gamma/gamma_state.c
@@ -0,0 +1,1734 @@
+/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_state.c,v 1.5 2002/11/05 17:46:07 tsi Exp $ */
+/*
+ * Copyright 2001 by Alan Hourihane.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <[email protected]>
+ *
+ * 3DLabs Gamma driver
+ */
+
+#include "gamma_context.h"
+#include "gamma_macros.h"
+#include "macros.h"
+#include "glint_dri.h"
+#include "colormac.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "array_cache/acache.h"
+#include "tnl/tnl.h"
+
+#define ENABLELIGHTING 0
+
+/* =============================================================
+ * Alpha blending
+ */
+
+static void gammaUpdateAlphaMode( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ CARD32 a = gmesa->AlphaTestMode;
+ CARD32 b = gmesa->AlphaBlendMode;
+ CARD32 f = gmesa->AB_FBReadMode_Save = 0;
+ GLubyte refByte = (GLint) (ctx->Color.AlphaRef * 255.0);
+
+ a &= ~(AT_CompareMask | AT_RefValueMask);
+ b &= ~(AB_SrcBlendMask | AB_DstBlendMask);
+
+ a |= refByte << 4;
+
+ switch ( ctx->Color.AlphaFunc ) {
+ case GL_NEVER:
+ a |= AT_Never;
+ break;
+ case GL_LESS:
+ a |= AT_Less;
+ break;
+ case GL_EQUAL:
+ a |= AT_Equal;
+ break;
+ case GL_LEQUAL:
+ a |= AT_LessEqual;
+ break;
+ case GL_GEQUAL:
+ a |= AT_GreaterEqual;
+ break;
+ case GL_GREATER:
+ a |= AT_Greater;
+ break;
+ case GL_NOTEQUAL:
+ a |= AT_NotEqual;
+ break;
+ case GL_ALWAYS:
+ a |= AT_Always;
+ break;
+ }
+
+ if ( ctx->Color.AlphaEnabled ) {
+ f |= FBReadDstEnable;
+ a |= AlphaTestModeEnable;
+ } else {
+ a &= ~AlphaTestModeEnable;
+ }
+
+ switch ( ctx->Color.BlendSrcRGB ) {
+ case GL_ZERO:
+ b |= AB_Src_Zero;
+ break;
+ case GL_ONE:
+ b |= AB_Src_One;
+ break;
+ case GL_DST_COLOR:
+ b |= AB_Src_DstColor;
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ b |= AB_Src_OneMinusDstColor;
+ break;
+ case GL_SRC_ALPHA:
+ b |= AB_Src_SrcAlpha;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ b |= AB_Src_OneMinusSrcAlpha;
+ break;
+ case GL_DST_ALPHA:
+ b |= AB_Src_DstAlpha;
+ f |= FBReadSrcEnable;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ b |= AB_Src_OneMinusDstAlpha;
+ f |= FBReadSrcEnable;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ b |= AB_Src_SrcAlphaSaturate;
+ break;
+ }
+
+ switch ( ctx->Color.BlendDstRGB ) {
+ case GL_ZERO:
+ b |= AB_Dst_Zero;
+ break;
+ case GL_ONE:
+ b |= AB_Dst_One;
+ break;
+ case GL_SRC_COLOR:
+ b |= AB_Dst_SrcColor;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ b |= AB_Dst_OneMinusSrcColor;
+ break;
+ case GL_SRC_ALPHA:
+ b |= AB_Dst_SrcAlpha;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ b |= AB_Dst_OneMinusSrcAlpha;
+ break;
+ case GL_DST_ALPHA:
+ b |= AB_Dst_DstAlpha;
+ f |= FBReadSrcEnable;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ b |= AB_Dst_OneMinusDstAlpha;
+ f |= FBReadSrcEnable;
+ break;
+ }
+
+ if ( ctx->Color.BlendEnabled ) {
+ f |= FBReadDstEnable;
+ b |= AlphaBlendModeEnable;
+ } else {
+ b &= ~AlphaBlendModeEnable;
+ }
+
+ if ( gmesa->AlphaTestMode != a ) {
+ gmesa->AlphaTestMode = a;
+ gmesa->dirty |= GAMMA_UPLOAD_ALPHA;
+ }
+ if ( gmesa->AlphaBlendMode != b) {
+ gmesa->AlphaBlendMode = b;
+ gmesa->dirty |= GAMMA_UPLOAD_BLEND;
+ }
+ gmesa->AB_FBReadMode_Save = f;
+}
+
+static void gammaDDAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ (void) ref;
+
+ FLUSH_BATCH( gmesa );
+
+ gmesa->new_state |= GAMMA_NEW_ALPHA;
+}
+
+static void gammaDDBlendEquation( GLcontext *ctx, GLenum mode )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+
+ gmesa->new_state |= GAMMA_NEW_ALPHA;
+}
+
+static void gammaDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+
+ gmesa->new_state |= GAMMA_NEW_ALPHA;
+}
+
+static void gammaDDBlendFuncSeparate( GLcontext *ctx,
+ GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+
+ gmesa->new_state |= GAMMA_NEW_ALPHA;
+}
+
+
+/* ================================================================
+ * Buffer clear
+ */
+
+static void gammaDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint cx, GLint cy, GLint cw, GLint ch )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)gmesa->driScreen->pDevPriv;
+ GLuint temp = 0;
+
+ FLUSH_BATCH( gmesa );
+
+ /* Update and emit any new state. We need to do this here to catch
+ * changes to the masks.
+ * FIXME: Just update the masks?
+ */
+ if ( gmesa->new_state )
+ gammaDDUpdateHWState( ctx );
+
+#ifdef DO_VALIDATE
+ /* Flush any partially filled buffers */
+ FLUSH_DMA_BUFFER(gmesa);
+
+ DRM_SPINLOCK(&gmesa->driScreen->pSAREA->drawable_lock,
+ gmesa->driScreen->drawLockID);
+ VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa);
+#endif
+
+ if (mask & DD_DEPTH_BIT) {
+ /* Turn off writes the FB */
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, FBWriteMode, FBWriteModeDisable);
+
+ mask &= ~DD_DEPTH_BIT;
+
+ /*
+ * Turn Rectangle2DControl off when the window is not clipped
+ * (i.e., the GID tests are not necessary). This dramatically
+ * increases the performance of the depth clears.
+ */
+ if (!gmesa->NotClipped) {
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, Rectangle2DControl, 1);
+ }
+
+ temp = (gmesa->LBReadMode & LBPartialProdMask) | LBWindowOriginBot;
+ if (gDRIPriv->numMultiDevices == 2) temp |= LBScanLineInt2;
+
+ CHECK_DMA_BUFFER(gmesa, 5);
+ WRITE(gmesa->buf, LBReadMode, temp);
+ WRITE(gmesa->buf, DeltaMode, DM_DepthEnable);
+ WRITE(gmesa->buf, DepthMode, (DepthModeEnable |
+ DM_Always |
+ DM_SourceDepthRegister |
+ DM_WriteMask));
+ WRITE(gmesa->buf, GLINTDepth, gmesa->ClearDepth);
+
+ /* Increment the frame count */
+ gmesa->FrameCount++;
+#ifdef FAST_CLEAR_4
+ gmesa->FrameCount &= 0x0f;
+#else
+ gmesa->FrameCount &= 0xff;
+#endif
+
+ /* Force FCP to be written */
+ WRITE(gmesa->buf, GLINTWindow, (WindowEnable |
+ W_PassIfEqual |
+ (gmesa->Window & W_GIDMask) |
+ W_DepthFCP |
+ W_LBUpdateFromRegisters |
+ W_OverrideWriteFiltering |
+ (gmesa->FrameCount << 9)));
+
+ /* Clear part of the depth and FCP buffers */
+ {
+ int y = gmesa->driScreen->fbHeight - gmesa->driDrawable->y - gmesa->driDrawable->h;
+ int x = gmesa->driDrawable->x;
+ int w = gmesa->driDrawable->w;
+ int h = gmesa->driDrawable->h;
+#ifndef TURN_OFF_FCP
+ float hsub = h;
+
+ if (gmesa->WindowChanged) {
+ gmesa->WindowChanged = GL_FALSE;
+ } else {
+#ifdef FAST_CLEAR_4
+ hsub /= 16;
+#else
+ hsub /= 256;
+#endif
+
+ /* Handle the case where the height < # of FCPs */
+ if (hsub < 1.0) {
+ if (gmesa->FrameCount > h)
+ gmesa->FrameCount = 0;
+ h = 1;
+ y += gmesa->FrameCount;
+ } else {
+ h = (gmesa->FrameCount+1)*hsub;
+ h -= (int)(gmesa->FrameCount*hsub);
+ y += gmesa->FrameCount*hsub;
+ }
+ }
+#endif
+ if (h && w) {
+#if 0
+ CHECK_DMA_BUFFER(gmesa, 2);
+ WRITE(gmesa->buf, Rectangle2DMode, ((h & 0xfff)<<12) |
+ (w & 0xfff) );
+ WRITE(gmesa->buf, DrawRectangle2D, ((y & 0xffff)<<16) |
+ (x & 0xffff) );
+#else
+ CHECK_DMA_BUFFER(gmesa, 8);
+ WRITE(gmesa->buf, StartXDom, x<<16);
+ WRITE(gmesa->buf, StartY, y<<16);
+ WRITE(gmesa->buf, StartXSub, (x+w)<<16);
+ WRITE(gmesa->buf, GLINTCount, h);
+ WRITE(gmesa->buf, dY, 1<<16);
+ WRITE(gmesa->buf, dXDom, 0<<16);
+ WRITE(gmesa->buf, dXSub, 0<<16);
+ WRITE(gmesa->buf, Render, 0x00000040); /* NOT_DONE */
+#endif
+ }
+ }
+
+ CHECK_DMA_BUFFER(gmesa, 6);
+ WRITE(gmesa->buf, DepthMode, gmesa->DepthMode);
+ WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode);
+ WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode);
+ WRITE(gmesa->buf, GLINTWindow, gmesa->Window);
+ WRITE(gmesa->buf, FastClearDepth, gmesa->ClearDepth);
+ WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable);
+
+ /* Turn on Depth FCP */
+ if (gmesa->Window & W_DepthFCP) {
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, WindowOr, (gmesa->FrameCount << 9));
+ }
+
+ /* Turn off GID clipping if window is not clipped */
+ if (gmesa->NotClipped) {
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, Rectangle2DControl, 0);
+ }
+ }
+
+ if (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) {
+ int y = gmesa->driScreen->fbHeight - gmesa->driDrawable->y - gmesa->driDrawable->h;
+ int x = gmesa->driDrawable->x;
+ int w = gmesa->driDrawable->w;
+ int h = gmesa->driDrawable->h;
+
+ mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
+
+ if (x < 0) { w -= -x; x = 0; }
+
+ /* Turn on GID clipping if window is clipped */
+ if (!gmesa->NotClipped) {
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, Rectangle2DControl, 1);
+ }
+
+ CHECK_DMA_BUFFER(gmesa, 18);
+ WRITE(gmesa->buf, FBBlockColor, gmesa->ClearColor);
+ WRITE(gmesa->buf, ColorDDAMode, ColorDDADisable);
+ WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable);
+ WRITE(gmesa->buf, DepthMode, 0);
+ WRITE(gmesa->buf, DeltaMode, 0);
+ WRITE(gmesa->buf, AlphaBlendMode, 0);
+#if 1
+ WRITE(gmesa->buf, dY, 1<<16);
+ WRITE(gmesa->buf, dXDom, 0<<16);
+ WRITE(gmesa->buf, dXSub, 0<<16);
+ WRITE(gmesa->buf, StartXSub, (x+w)<<16);
+ WRITE(gmesa->buf, GLINTCount, h);
+ WRITE(gmesa->buf, StartXDom, x<<16);
+ WRITE(gmesa->buf, StartY, y<<16);
+ WRITE(gmesa->buf, Render, 0x00000048); /* NOT_DONE */
+#else
+ WRITE(gmesa->buf, Rectangle2DMode, (((h & 0xfff)<<12) |
+ (w & 0xfff)));
+ WRITE(gmesa->buf, DrawRectangle2D, (((y & 0xffff)<<16) |
+ (x & 0xffff)));
+#endif
+ WRITE(gmesa->buf, DepthMode, gmesa->DepthMode);
+ WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode);
+ WRITE(gmesa->buf, AlphaBlendMode, gmesa->AlphaBlendMode);
+ WRITE(gmesa->buf, ColorDDAMode, gmesa->ColorDDAMode);
+
+ /* Turn off GID clipping if window is clipped */
+ if (gmesa->NotClipped) {
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, Rectangle2DControl, 0);
+ }
+ }
+
+#ifdef DO_VALIDATE
+ PROCESS_DMA_BUFFER_TOP_HALF(gmesa);
+
+ DRM_SPINUNLOCK(&gmesa->driScreen->pSAREA->drawable_lock,
+ gmesa->driScreen->drawLockID);
+ VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa);
+
+ PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa);
+#endif
+
+ if ( mask )
+ _swrast_Clear( ctx, mask, all, cx, cy, cw, ch );
+}
+
+/* =============================================================
+ * Depth testing
+ */
+
+static void gammaUpdateZMode( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ CARD32 z = gmesa->DepthMode;
+ CARD32 delta = gmesa->DeltaMode;
+ CARD32 window = gmesa->Window;
+ CARD32 lbread = gmesa->LBReadMode;
+
+ z &= ~DM_CompareMask;
+
+ switch ( ctx->Depth.Func ) {
+ case GL_NEVER:
+ z |= DM_Never;
+ break;
+ case GL_ALWAYS:
+ z |= DM_Always;
+ break;
+ case GL_LESS:
+ z |= DM_Less;
+ break;
+ case GL_LEQUAL:
+ z |= DM_LessEqual;
+ break;
+ case GL_EQUAL:
+ z |= DM_Equal;
+ break;
+ case GL_GEQUAL:
+ z |= DM_GreaterEqual;
+ break;
+ case GL_GREATER:
+ z |= DM_Greater;
+ break;
+ case GL_NOTEQUAL:
+ z |= DM_NotEqual;
+ break;
+ }
+
+ if ( ctx->Depth.Test ) {
+ z |= DepthModeEnable;
+ delta |= DM_DepthEnable;
+ window |= W_DepthFCP;
+ lbread |= LBReadDstEnable;
+ } else {
+ z &= ~DepthModeEnable;
+ delta &= ~DM_DepthEnable;
+ window &= ~W_DepthFCP;
+ lbread &= ~LBReadDstEnable;
+ }
+
+ if ( ctx->Depth.Mask ) {
+ z |= DM_WriteMask;
+ } else {
+ z &= ~DM_WriteMask;
+ }
+
+#if 0
+ if ( gmesa->DepthMode != z ){
+#endif
+ gmesa->DepthMode = z;
+ gmesa->DeltaMode = delta;
+ gmesa->Window = window;
+ gmesa->LBReadMode = lbread;
+ gmesa->dirty |= GAMMA_UPLOAD_DEPTH;
+#if 0
+ }
+#endif
+}
+
+static void gammaDDDepthFunc( GLcontext *ctx, GLenum func )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_DEPTH;
+}
+
+static void gammaDDDepthMask( GLcontext *ctx, GLboolean flag )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_DEPTH;
+}
+
+static void gammaDDClearDepth( GLcontext *ctx, GLclampd d )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ switch ( gmesa->DepthSize ) {
+ case 16:
+ gmesa->ClearDepth = d * 0x0000ffff;
+ break;
+ case 24:
+ gmesa->ClearDepth = d * 0x00ffffff;
+ break;
+ case 32:
+ gmesa->ClearDepth = d * 0xffffffff;
+ break;
+ }
+}
+
+static void gammaDDFinish( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_DMA_BUFFER(gmesa);
+}
+
+static void gammaDDFlush( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_DMA_BUFFER(gmesa);
+}
+
+/* =============================================================
+ * Fog
+ */
+
+static void gammaUpdateFogAttrib( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ CARD32 f = gmesa->FogMode;
+ CARD32 g = gmesa->GeometryMode;
+ CARD32 d = gmesa->DeltaMode;
+
+ if (ctx->Fog.Enabled) {
+ f |= FogModeEnable;
+ g |= GM_FogEnable;
+ d |= DM_FogEnable;
+ } else {
+ f &= ~FogModeEnable;
+ g &= ~GM_FogEnable;
+ d &= ~DM_FogEnable;
+ }
+
+ g &= ~GM_FogMask;
+
+ switch (ctx->Fog.Mode) {
+ case GL_LINEAR:
+ g |= GM_FogLinear;
+ break;
+ case GL_EXP:
+ g |= GM_FogExp;
+ break;
+ case GL_EXP2:
+ g |= GM_FogExpSquared;
+ break;
+ }
+
+ if ( gmesa->FogMode != f ) {
+ gmesa->FogMode = f;
+ gmesa->dirty |= GAMMA_UPLOAD_FOG;
+ }
+
+ if ( gmesa->GeometryMode != g ) {
+ gmesa->GeometryMode = g;
+ gmesa->dirty |= GAMMA_UPLOAD_GEOMETRY;
+ }
+
+ if ( gmesa->DeltaMode != d ) {
+ gmesa->DeltaMode = d;
+ gmesa->dirty |= GAMMA_UPLOAD_DEPTH;
+ }
+}
+
+static void gammaDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_FOG;
+}
+
+/* =============================================================
+ * Lines
+ */
+static void gammaDDLineWidth( GLcontext *ctx, GLfloat width )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ CHECK_DMA_BUFFER(gmesa, 3);
+ WRITE(gmesa->buf, LineWidth, (GLuint)width);
+ WRITEF(gmesa->buf, AAlineWidth, width);
+ WRITE(gmesa->buf, LineWidthOffset, (GLuint)(width-1)/2);
+}
+
+static void gammaDDLineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ gmesa->LineMode &= ~(LM_StippleMask | LM_RepeatFactorMask);
+ gmesa->LineMode |= ((GLuint)(factor - 1) << 1) | ((GLuint)pattern << 10);
+
+ gmesa->dirty |= GAMMA_UPLOAD_LINEMODE;
+}
+
+
+
+/* =============================================================
+ * Points
+ */
+static void gammaDDPointSize( GLcontext *ctx, GLfloat size )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ CHECK_DMA_BUFFER(gmesa, 2);
+ WRITE(gmesa->buf, PointSize, (GLuint)size);
+ WRITEF(gmesa->buf, AApointSize, size);
+}
+
+/* =============================================================
+ * Polygon
+ */
+
+static void gammaUpdatePolygon( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ CARD32 g = gmesa->GeometryMode;
+
+ g &= ~(GM_PolyOffsetFillEnable | GM_PolyOffsetPointEnable |
+ GM_PolyOffsetLineEnable);
+
+ if (ctx->Polygon.OffsetFill) g |= GM_PolyOffsetFillEnable;
+ if (ctx->Polygon.OffsetPoint) g |= GM_PolyOffsetPointEnable;
+ if (ctx->Polygon.OffsetLine) g |= GM_PolyOffsetLineEnable;
+
+ g &= ~GM_FB_PolyMask;
+
+ switch (ctx->Polygon.FrontMode) {
+ case GL_FILL:
+ g |= GM_FrontPolyFill;
+ break;
+ case GL_LINE:
+ g |= GM_FrontPolyLine;
+ break;
+ case GL_POINT:
+ g |= GM_FrontPolyPoint;
+ break;
+ }
+
+ switch (ctx->Polygon.BackMode) {
+ case GL_FILL:
+ g |= GM_BackPolyFill;
+ break;
+ case GL_LINE:
+ g |= GM_BackPolyLine;
+ break;
+ case GL_POINT:
+ g |= GM_BackPolyPoint;
+ break;
+ }
+
+ if ( gmesa->GeometryMode != g ) {
+ gmesa->GeometryMode = g;
+ gmesa->dirty |= GAMMA_UPLOAD_GEOMETRY;
+ }
+
+ gmesa->dirty |= GAMMA_UPLOAD_POLYGON;
+}
+
+static void gammaDDPolygonMode( GLcontext *ctx, GLenum face, GLenum mode)
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+
+ gmesa->new_state |= GAMMA_NEW_POLYGON;
+}
+
+static void gammaUpdateStipple( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+
+ if (ctx->Polygon.StippleFlag) {
+ gmesa->AreaStippleMode |= AreaStippleModeEnable/* | ASM_X32 | ASM_Y32*/;
+ } else {
+ gmesa->AreaStippleMode &= ~AreaStippleModeEnable;
+ }
+
+ gmesa->dirty |= GAMMA_UPLOAD_STIPPLE;
+}
+
+static void gammaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask)
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_STIPPLE;
+}
+
+/* =============================================================
+ * Clipping
+ */
+
+static void gammaUpdateClipping( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ GLint x1, y1, x2, y2;
+
+ if ( gmesa->driDrawable ) {
+ x1 = gmesa->driDrawable->x + ctx->Scissor.X;
+ y1 = gmesa->driScreen->fbHeight -
+ (gmesa->driDrawable->y +
+ gmesa->driDrawable->h) + ctx->Scissor.Y;
+ x2 = x1 + ctx->Scissor.Width;
+ y2 = y1 + ctx->Scissor.Height;
+
+ gmesa->ScissorMinXY = x1 | (y1 << 16);
+ gmesa->ScissorMaxXY = x2 | (y2 << 16);
+ if (ctx->Scissor.Enabled)
+ gmesa->ScissorMode |= UserScissorEnable;
+ else
+ gmesa->ScissorMode &= ~UserScissorEnable;
+
+ gmesa->dirty |= GAMMA_UPLOAD_CLIP;
+ }
+}
+
+static void gammaDDScissor( GLcontext *ctx,
+ GLint x, GLint y, GLsizei w, GLsizei h )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_CLIP;
+}
+
+/* =============================================================
+ * Culling
+ */
+
+static void gammaUpdateCull( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ CARD32 g = gmesa->GeometryMode;
+
+ g &= ~(GM_PolyCullMask | GM_FFMask);
+
+ if (ctx->Polygon.FrontFace == GL_CCW) {
+ g |= GM_FrontFaceCCW;
+ } else {
+ g |= GM_FrontFaceCW;
+ }
+
+ switch ( ctx->Polygon.CullFaceMode ) {
+ case GL_FRONT:
+ g |= GM_PolyCullFront;
+ break;
+ case GL_BACK:
+ g |= GM_PolyCullBack;
+ break;
+ case GL_FRONT_AND_BACK:
+ g |= GM_PolyCullBoth;
+ break;
+ }
+
+ if ( ctx->Polygon.CullFlag ) {
+ g |= GM_PolyCullEnable;
+ } else {
+ g &= ~GM_PolyCullEnable;
+ }
+
+ if ( gmesa->GeometryMode != g ) {
+ gmesa->GeometryMode = g;
+ gmesa->dirty |= GAMMA_UPLOAD_GEOMETRY;
+ }
+}
+
+static void gammaDDCullFace( GLcontext *ctx, GLenum mode )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_CULL;
+}
+
+static void gammaDDFrontFace( GLcontext *ctx, GLenum mode )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_CULL;
+}
+
+/* =============================================================
+ * Masks
+ */
+
+static void gammaUpdateMasks( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+
+ GLuint mask = gammaPackColor( gmesa->gammaScreen->cpp,
+ ctx->Color.ColorMask[RCOMP],
+ ctx->Color.ColorMask[GCOMP],
+ ctx->Color.ColorMask[BCOMP],
+ ctx->Color.ColorMask[ACOMP] );
+
+ if (gmesa->gammaScreen->cpp == 2) mask |= mask << 16;
+
+ if ( gmesa->FBHardwareWriteMask != mask ) {
+ gmesa->FBHardwareWriteMask = mask;
+ gmesa->dirty |= GAMMA_UPLOAD_MASKS;
+ }
+}
+
+static void gammaDDColorMask( GLcontext *ctx, GLboolean r, GLboolean g,
+ GLboolean b, GLboolean a)
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_MASKS;
+}
+
+/* =============================================================
+ * Rendering attributes
+ *
+ * We really don't want to recalculate all this every time we bind a
+ * texture. These things shouldn't change all that often, so it makes
+ * sense to break them out of the core texture state update routines.
+ */
+
+#if ENABLELIGHTING
+static void gammaDDLightfv(GLcontext *ctx, GLenum light, GLenum pname,
+ const GLfloat *params, GLint nParams)
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ GLfloat l,x,y,z,w;
+
+ switch(light) {
+ case GL_LIGHT0:
+ switch (pname) {
+ case GL_AMBIENT:
+ CHECK_DMA_BUFFER(gmesa, 3);
+ /* We don't do alpha */
+ WRITEF(gmesa->buf, Light0AmbientIntensityBlue, params[2]);
+ WRITEF(gmesa->buf, Light0AmbientIntensityGreen, params[1]);
+ WRITEF(gmesa->buf, Light0AmbientIntensityRed, params[0]);
+ break;
+ case GL_DIFFUSE:
+ CHECK_DMA_BUFFER(gmesa, 3);
+ /* We don't do alpha */
+ WRITEF(gmesa->buf, Light0DiffuseIntensityBlue, params[2]);
+ WRITEF(gmesa->buf, Light0DiffuseIntensityGreen, params[1]);
+ WRITEF(gmesa->buf, Light0DiffuseIntensityRed, params[0]);
+ break;
+ case GL_SPECULAR:
+ CHECK_DMA_BUFFER(gmesa, 3);
+ /* We don't do alpha */
+ WRITEF(gmesa->buf, Light0SpecularIntensityBlue, params[2]);
+ WRITEF(gmesa->buf, Light0SpecularIntensityGreen, params[1]);
+ WRITEF(gmesa->buf, Light0SpecularIntensityRed, params[0]);
+ break;
+ case GL_POSITION:
+ /* Normalize <x,y,z> */
+ x = params[0]; y = params[1]; z = params[2]; w = params[3];
+ l = sqrt(x*x + y*y + z*z + w*w);
+ w /= l;
+ x /= l;
+ y /= l;
+ z /= l;
+ if (params[3] != 0.0) {
+ gmesa->Light0Mode |= Light0ModeAttenuation;
+ gmesa->Light0Mode |= Light0ModeLocal;
+ } else {
+ gmesa->Light0Mode &= ~Light0ModeAttenuation;
+ gmesa->Light0Mode &= ~Light0ModeLocal;
+ }
+ CHECK_DMA_BUFFER(gmesa, 5);
+ WRITE(gmesa->buf, Light0Mode, gmesa->Light0Mode);
+ WRITEF(gmesa->buf, Light0PositionW, w);
+ WRITEF(gmesa->buf, Light0PositionZ, z);
+ WRITEF(gmesa->buf, Light0PositionY, y);
+ WRITEF(gmesa->buf, Light0PositionX, x);
+ break;
+ case GL_SPOT_DIRECTION:
+ CHECK_DMA_BUFFER(gmesa, 3);
+ /* WRITEF(gmesa->buf, Light0SpotlightDirectionW, params[3]); */
+ WRITEF(gmesa->buf, Light0SpotlightDirectionZ, params[2]);
+ WRITEF(gmesa->buf, Light0SpotlightDirectionY, params[1]);
+ WRITEF(gmesa->buf, Light0SpotlightDirectionX, params[0]);
+ break;
+ case GL_SPOT_EXPONENT:
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITEF(gmesa->buf, Light0SpotlightExponent, params[0]);
+ break;
+ case GL_SPOT_CUTOFF:
+ if (params[0] != 180.0)
+ gmesa->Light0Mode |= Light0ModeSpotLight;
+ else
+ gmesa->Light0Mode &= ~Light0ModeSpotLight;
+ CHECK_DMA_BUFFER(gmesa, 2);
+ WRITE(gmesa->buf, Light0Mode, gmesa->Light0Mode);
+ WRITEF(gmesa->buf, Light0CosSpotlightCutoffAngle, cos(params[0]*DEG2RAD));
+ break;
+ case GL_CONSTANT_ATTENUATION:
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITEF(gmesa->buf, Light0ConstantAttenuation, params[0]);
+ break;
+ case GL_LINEAR_ATTENUATION:
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITEF(gmesa->buf, Light0LinearAttenuation, params[0]);
+ break;
+ case GL_QUADRATIC_ATTENUATION:
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITEF(gmesa->buf, Light0QuadraticAttenuation, params[0]);
+ break;
+ }
+ break;
+ }
+}
+
+static void gammaDDLightModelfv( GLcontext *ctx, GLenum pname,
+ const GLfloat *params )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ switch (pname) {
+ case GL_LIGHT_MODEL_AMBIENT:
+ CHECK_DMA_BUFFER(gmesa, 3);
+ /* We don't do alpha */
+ WRITEF(gmesa->buf, SceneAmbientColorBlue, params[2]);
+ WRITEF(gmesa->buf, SceneAmbientColorGreen, params[1]);
+ WRITEF(gmesa->buf, SceneAmbientColorRed, params[0]);
+ break;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ if (params[0] != 0.0)
+ gmesa->LightingMode |= LightingModeLocalViewer;
+ else
+ gmesa->LightingMode &= ~LightingModeLocalViewer;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, LightingMode, gmesa->LightingMode);
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ if (params[0] == 1.0f) {
+ gmesa->LightingMode |= LightingModeTwoSides;
+ gmesa->MaterialMode |= MaterialModeTwoSides;
+ } else {
+ gmesa->LightingMode &= ~LightingModeTwoSides;
+ gmesa->MaterialMode &= ~MaterialModeTwoSides;
+ }
+ CHECK_DMA_BUFFER(gmesa, 2);
+ WRITE(gmesa->buf, LightingMode, gmesa->LightingMode);
+ WRITE(gmesa->buf, MaterialMode, gmesa->MaterialMode);
+ break;
+ }
+}
+#endif
+
+static void gammaDDShadeModel( GLcontext *ctx, GLenum mode )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ CARD32 g = gmesa->GeometryMode;
+ CARD32 c = gmesa->ColorDDAMode;
+
+ g &= ~GM_ShadingMask;
+ c &= ~ColorDDAShadingMask;
+
+ switch ( mode ) {
+ case GL_FLAT:
+ g |= GM_FlatShading;
+ c |= ColorDDAFlat;
+ break;
+ case GL_SMOOTH:
+ g |= GM_GouraudShading;
+ c |= ColorDDAGouraud;
+ break;
+ default:
+ return;
+ }
+
+ if ( gmesa->ColorDDAMode != c ) {
+ FLUSH_BATCH( gmesa );
+ gmesa->ColorDDAMode = c;
+
+ gmesa->dirty |= GAMMA_UPLOAD_SHADE;
+ }
+
+ if ( gmesa->GeometryMode != g ) {
+ FLUSH_BATCH( gmesa );
+ gmesa->GeometryMode = g;
+
+ gmesa->dirty |= GAMMA_UPLOAD_GEOMETRY;
+ }
+}
+
+/* =============================================================
+ * Miscellaneous
+ */
+
+static void gammaDDClearColor( GLcontext *ctx, const GLfloat color[4])
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ GLubyte c[4];
+ UNCLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
+ UNCLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
+ UNCLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
+ UNCLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
+
+ gmesa->ClearColor = gammaPackColor( gmesa->gammaScreen->cpp,
+ c[0], c[1], c[2], c[3] );
+
+ if (gmesa->gammaScreen->cpp == 2) gmesa->ClearColor |= gmesa->ClearColor<<16;
+}
+
+
+static void gammaDDLogicalOpcode( GLcontext *ctx, GLenum opcode )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+
+ if ( ctx->Color.ColorLogicOpEnabled ) {
+ gmesa->LogicalOpMode = opcode << 1 | LogicalOpModeEnable;
+ } else {
+ gmesa->LogicalOpMode = LogicalOpModeDisable;
+ }
+
+ gmesa->dirty |= GAMMA_UPLOAD_LOGICOP;
+}
+
+static void gammaDDDrawBuffer( GLcontext *ctx, GLenum mode )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ FLUSH_BATCH( gmesa );
+
+ switch ( mode ) {
+ case GL_FRONT_LEFT:
+ gmesa->drawOffset = gmesa->readOffset = 0;
+ break;
+ case GL_BACK_LEFT:
+ gmesa->drawOffset = gmesa->readOffset = gmesa->driScreen->fbHeight * gmesa->driScreen->fbWidth * gmesa->gammaScreen->cpp;
+ break;
+ }
+}
+
+static void gammaDDReadBuffer( GLcontext *ctx, GLenum mode )
+{
+ /* XXX anything? */
+}
+
+/* =============================================================
+ * Window position and viewport transformation
+ */
+
+void gammaUpdateWindow( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = gmesa->driDrawable;
+ GLfloat xoffset = (GLfloat)dPriv->x;
+ GLfloat yoffset = gmesa->driScreen->fbHeight - (GLfloat)dPriv->y - dPriv->h;
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+
+ GLfloat sx = v[MAT_SX];
+ GLfloat tx = v[MAT_TX] + xoffset;
+ GLfloat sy = v[MAT_SY];
+ GLfloat ty = v[MAT_TY] + yoffset;
+ GLfloat sz = v[MAT_SZ] * gmesa->depth_scale;
+ GLfloat tz = v[MAT_TZ] * gmesa->depth_scale;
+
+ gmesa->dirty |= GAMMA_UPLOAD_VIEWPORT;
+
+ gmesa->ViewportScaleX = sx;
+ gmesa->ViewportScaleY = sy;
+ gmesa->ViewportScaleZ = sz;
+ gmesa->ViewportOffsetX = tx;
+ gmesa->ViewportOffsetY = ty;
+ gmesa->ViewportOffsetZ = tz;
+}
+
+
+
+static void gammaDDViewport( GLcontext *ctx, GLint x, GLint y,
+ GLsizei width, GLsizei height )
+{
+ gammaUpdateWindow( ctx );
+}
+
+static void gammaDDDepthRange( GLcontext *ctx, GLclampd nearval,
+ GLclampd farval )
+{
+ gammaUpdateWindow( ctx );
+}
+
+void gammaUpdateViewportOffset( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ __DRIdrawablePrivate *dPriv = gmesa->driDrawable;
+ GLfloat xoffset = (GLfloat)dPriv->x;
+ GLfloat yoffset = gmesa->driScreen->fbHeight - (GLfloat)dPriv->y - dPriv->h;
+ const GLfloat *v = ctx->Viewport._WindowMap.m;
+
+ GLfloat tx = v[MAT_TX] + xoffset;
+ GLfloat ty = v[MAT_TY] + yoffset;
+
+ if ( gmesa->ViewportOffsetX != tx ||
+ gmesa->ViewportOffsetY != ty )
+ {
+ gmesa->ViewportOffsetX = tx;
+ gmesa->ViewportOffsetY = ty;
+
+ gmesa->new_state |= GAMMA_NEW_WINDOW;
+ }
+
+ gmesa->new_state |= GAMMA_NEW_CLIP;
+}
+
+#if 0
+/*
+ * Matrix
+ */
+
+static void gammaLoadHWMatrix(GLcontext *ctx)
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ const GLfloat *m;
+
+ gmesa->TransformMode &= ~XM_XformTexture;
+
+ switch (ctx->Transform.MatrixMode) {
+ case GL_MODELVIEW:
+ gmesa->TransformMode |= XM_UseModelViewMatrix;
+ m = ctx->ModelviewMatrixStack.Top->m;
+ CHECK_DMA_BUFFER(gmesa, 16);
+ WRITEF(gmesa->buf, ModelViewMatrix0, m[0]);
+ WRITEF(gmesa->buf, ModelViewMatrix1, m[1]);
+ WRITEF(gmesa->buf, ModelViewMatrix2, m[2]);
+ WRITEF(gmesa->buf, ModelViewMatrix3, m[3]);
+ WRITEF(gmesa->buf, ModelViewMatrix4, m[4]);
+ WRITEF(gmesa->buf, ModelViewMatrix5, m[5]);
+ WRITEF(gmesa->buf, ModelViewMatrix6, m[6]);
+ WRITEF(gmesa->buf, ModelViewMatrix7, m[7]);
+ WRITEF(gmesa->buf, ModelViewMatrix8, m[8]);
+ WRITEF(gmesa->buf, ModelViewMatrix9, m[9]);
+ WRITEF(gmesa->buf, ModelViewMatrix10, m[10]);
+ WRITEF(gmesa->buf, ModelViewMatrix11, m[11]);
+ WRITEF(gmesa->buf, ModelViewMatrix12, m[12]);
+ WRITEF(gmesa->buf, ModelViewMatrix13, m[13]);
+ WRITEF(gmesa->buf, ModelViewMatrix14, m[14]);
+ WRITEF(gmesa->buf, ModelViewMatrix15, m[15]);
+ break;
+ case GL_PROJECTION:
+ m = ctx->ProjectionMatrixStack.Top->m;
+ CHECK_DMA_BUFFER(gmesa, 16);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix0, m[0]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix1, m[1]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix2, m[2]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix3, m[3]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix4, m[4]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix5, m[5]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix6, m[6]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix7, m[7]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix8, m[8]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix9, m[9]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix10, m[10]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix11, m[11]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix12, m[12]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix13, m[13]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix14, m[14]);
+ WRITEF(gmesa->buf, ModelViewProjectionMatrix15, m[15]);
+ break;
+ case GL_TEXTURE:
+ m = ctx->TextureMatrixStack[0].Top->m;
+ CHECK_DMA_BUFFER(gmesa, 16);
+ gmesa->TransformMode |= XM_XformTexture;
+ WRITEF(gmesa->buf, TextureMatrix0, m[0]);
+ WRITEF(gmesa->buf, TextureMatrix1, m[1]);
+ WRITEF(gmesa->buf, TextureMatrix2, m[2]);
+ WRITEF(gmesa->buf, TextureMatrix3, m[3]);
+ WRITEF(gmesa->buf, TextureMatrix4, m[4]);
+ WRITEF(gmesa->buf, TextureMatrix5, m[5]);
+ WRITEF(gmesa->buf, TextureMatrix6, m[6]);
+ WRITEF(gmesa->buf, TextureMatrix7, m[7]);
+ WRITEF(gmesa->buf, TextureMatrix8, m[8]);
+ WRITEF(gmesa->buf, TextureMatrix9, m[9]);
+ WRITEF(gmesa->buf, TextureMatrix10, m[10]);
+ WRITEF(gmesa->buf, TextureMatrix11, m[11]);
+ WRITEF(gmesa->buf, TextureMatrix12, m[12]);
+ WRITEF(gmesa->buf, TextureMatrix13, m[13]);
+ WRITEF(gmesa->buf, TextureMatrix14, m[14]);
+ WRITEF(gmesa->buf, TextureMatrix15, m[15]);
+ break;
+
+ default:
+ /* ERROR!!! -- how did this happen? */
+ break;
+ }
+
+ gmesa->dirty |= GAMMA_UPLOAD_TRANSFORM;
+}
+#endif
+
+/* =============================================================
+ * State enable/disable
+ */
+
+static void gammaDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+
+ switch ( cap ) {
+ case GL_ALPHA_TEST:
+ case GL_BLEND:
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_ALPHA;
+ break;
+
+ case GL_CULL_FACE:
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_CULL;
+ break;
+
+ case GL_DEPTH_TEST:
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_DEPTH;
+ break;
+
+ case GL_DITHER:
+ do {
+ CARD32 d = gmesa->DitherMode;
+ FLUSH_BATCH( gmesa );
+
+ if ( state ) {
+ d |= DM_DitherEnable;
+ } else {
+ d &= ~DM_DitherEnable;
+ }
+
+ if ( gmesa->DitherMode != d ) {
+ gmesa->DitherMode = d;
+ gmesa->dirty |= GAMMA_UPLOAD_DITHER;
+ }
+ } while (0);
+ break;
+
+#if 0
+ case GL_FOG:
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_FOG;
+ break;
+#endif
+
+ case GL_INDEX_LOGIC_OP:
+ case GL_COLOR_LOGIC_OP:
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_LOGICOP;
+ break;
+
+#if ENABLELIGHTING
+ case GL_LIGHTING:
+ do {
+ CARD32 l = gmesa->LightingMode;
+ FLUSH_BATCH( gmesa );
+
+ if ( state ) {
+ l |= LightingModeEnable;
+ } else {
+ l &= ~LightingModeEnable;
+ }
+
+ if ( gmesa->LightingMode != l ) {
+ gmesa->LightingMode = l;
+ gmesa->dirty |= GAMMA_UPLOAD_LIGHT;
+ }
+ } while (0);
+ break;
+
+ case GL_COLOR_MATERIAL:
+ do {
+ CARD32 m = gmesa->MaterialMode;
+ FLUSH_BATCH( gmesa );
+
+ if ( state ) {
+ m |= MaterialModeEnable;
+ } else {
+ m &= ~MaterialModeEnable;
+ }
+
+ if ( gmesa->MaterialMode != m ) {
+ gmesa->MaterialMode = m;
+ gmesa->dirty |= GAMMA_UPLOAD_LIGHT;
+ }
+ } while (0);
+ break;
+#endif
+
+ case GL_LINE_SMOOTH:
+ FLUSH_BATCH( gmesa );
+ if ( state ) {
+ gmesa->AntialiasMode |= AntialiasModeEnable;
+ gmesa->LineMode |= LM_AntialiasEnable;
+ } else {
+ gmesa->AntialiasMode &= ~AntialiasModeEnable;
+ gmesa->LineMode &= ~LM_AntialiasEnable;
+ }
+ gmesa->dirty |= GAMMA_UPLOAD_LINEMODE;
+ break;
+
+ case GL_POINT_SMOOTH:
+ FLUSH_BATCH( gmesa );
+ if ( state ) {
+ gmesa->AntialiasMode |= AntialiasModeEnable;
+ gmesa->PointMode |= PM_AntialiasEnable;
+ } else {
+ gmesa->AntialiasMode &= ~AntialiasModeEnable;
+ gmesa->PointMode &= ~PM_AntialiasEnable;
+ }
+ gmesa->dirty |= GAMMA_UPLOAD_POINTMODE;
+ break;
+
+ case GL_POLYGON_SMOOTH:
+ FLUSH_BATCH( gmesa );
+ if ( state ) {
+ gmesa->AntialiasMode |= AntialiasModeEnable;
+ gmesa->TriangleMode |= TM_AntialiasEnable;
+ } else {
+ gmesa->AntialiasMode &= ~AntialiasModeEnable;
+ gmesa->TriangleMode &= ~TM_AntialiasEnable;
+ }
+ gmesa->dirty |= GAMMA_UPLOAD_TRIMODE;
+ break;
+
+ case GL_SCISSOR_TEST:
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_CLIP;
+ break;
+
+ case GL_POLYGON_OFFSET_FILL:
+ case GL_POLYGON_OFFSET_POINT:
+ case GL_POLYGON_OFFSET_LINE:
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_POLYGON;
+ break;
+
+ case GL_LINE_STIPPLE:
+ FLUSH_BATCH( gmesa );
+ if ( state )
+ gmesa->LineMode |= LM_StippleEnable;
+ else
+ gmesa->LineMode &= ~LM_StippleEnable;
+ gmesa->dirty |= GAMMA_UPLOAD_LINEMODE;
+ break;
+
+ case GL_POLYGON_STIPPLE:
+ FLUSH_BATCH( gmesa );
+ gmesa->new_state |= GAMMA_NEW_STIPPLE;
+ break;
+
+ default:
+ return;
+ }
+}
+
+/* =============================================================
+ * State initialization, management
+ */
+
+
+/*
+ * Load the current context's state into the hardware.
+ *
+ * NOTE: Be VERY careful about ensuring the context state is marked for
+ * upload, the only place it shouldn't be uploaded is when the setup
+ * state has changed in ReducedPrimitiveChange as this comes right after
+ * a state update.
+ *
+ * Blits of any type should always upload the context and masks after
+ * they are done.
+ */
+void gammaEmitHwState( gammaContextPtr gmesa )
+{
+ if (!gmesa->driDrawable) return;
+
+ if (!gmesa->dirty) return;
+
+#ifdef DO_VALIDATE
+ /* Flush any partially filled buffers */
+ FLUSH_DMA_BUFFER(gmesa);
+
+ DRM_SPINLOCK(&gmesa->driScreen->pSAREA->drawable_lock,
+ gmesa->driScreen->drawLockID);
+ VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa);
+#endif
+
+ if (gmesa->dirty & GAMMA_UPLOAD_VIEWPORT) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_VIEWPORT;
+ CHECK_DMA_BUFFER(gmesa, 6);
+ WRITEF(gmesa->buf, ViewPortOffsetX, gmesa->ViewportOffsetX);
+ WRITEF(gmesa->buf, ViewPortOffsetY, gmesa->ViewportOffsetY);
+ WRITEF(gmesa->buf, ViewPortOffsetZ, gmesa->ViewportOffsetZ);
+ WRITEF(gmesa->buf, ViewPortScaleX, gmesa->ViewportScaleX);
+ WRITEF(gmesa->buf, ViewPortScaleY, gmesa->ViewportScaleY);
+ WRITEF(gmesa->buf, ViewPortScaleZ, gmesa->ViewportScaleZ);
+ }
+ if ( (gmesa->dirty & GAMMA_UPLOAD_POINTMODE) ||
+ (gmesa->dirty & GAMMA_UPLOAD_LINEMODE) ||
+ (gmesa->dirty & GAMMA_UPLOAD_TRIMODE) ) {
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, AntialiasMode, gmesa->AntialiasMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_POINTMODE) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_POINTMODE;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, PointMode, gmesa->PointMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_LINEMODE) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_LINEMODE;
+ CHECK_DMA_BUFFER(gmesa, 2);
+ WRITE(gmesa->buf, LineMode, gmesa->LineMode);
+ WRITE(gmesa->buf, LineStippleMode, gmesa->LineMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_TRIMODE) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_TRIMODE;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, TriangleMode, gmesa->TriangleMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_FOG) {
+ GLchan c[3], col;
+ UNCLAMPED_FLOAT_TO_RGB_CHAN( c, gmesa->glCtx->Fog.Color );
+ col = gammaPackColor(4, c[0], c[1], c[2], 0);
+ gmesa->dirty &= ~GAMMA_UPLOAD_FOG;
+ CHECK_DMA_BUFFER(gmesa, 5);
+#if 0
+ WRITE(gmesa->buf, FogMode, gmesa->FogMode);
+ WRITE(gmesa->buf, FogColor, col);
+ WRITEF(gmesa->buf, FStart, gmesa->glCtx->Fog.Start);
+#endif
+ WRITEF(gmesa->buf, FogEnd, gmesa->glCtx->Fog.End);
+ WRITEF(gmesa->buf, FogDensity, gmesa->glCtx->Fog.Density);
+ WRITEF(gmesa->buf, FogScale,
+ 1.0f/(gmesa->glCtx->Fog.End - gmesa->glCtx->Fog.Start));
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_DITHER) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_DITHER;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, DitherMode, gmesa->DitherMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_LOGICOP) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_LOGICOP;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, LogicalOpMode, gmesa->LogicalOpMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_CLIP) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_CLIP;
+ CHECK_DMA_BUFFER(gmesa, 3);
+ WRITE(gmesa->buf, ScissorMinXY, gmesa->ScissorMinXY);
+ WRITE(gmesa->buf, ScissorMaxXY, gmesa->ScissorMaxXY);
+ WRITE(gmesa->buf, ScissorMode, gmesa->ScissorMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_MASKS) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_MASKS;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, FBHardwareWriteMask, gmesa->FBHardwareWriteMask);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_ALPHA) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_ALPHA;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, AlphaTestMode, gmesa->AlphaTestMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_BLEND) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_BLEND;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, AlphaBlendMode, gmesa->AlphaBlendMode);
+ }
+ CHECK_DMA_BUFFER(gmesa, 1);
+ if (gmesa->glCtx->Color.BlendEnabled || gmesa->glCtx->Color.AlphaEnabled) {
+ WRITE(gmesa->buf, FBReadMode, gmesa->FBReadMode | gmesa->AB_FBReadMode_Save);
+ } else {
+ WRITE(gmesa->buf, FBReadMode, gmesa->FBReadMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_LIGHT) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_LIGHT;
+ CHECK_DMA_BUFFER(gmesa, 2);
+ WRITE(gmesa->buf, LightingMode, gmesa->LightingMode);
+ WRITE(gmesa->buf, MaterialMode, gmesa->MaterialMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_SHADE) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_SHADE;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, ColorDDAMode, gmesa->ColorDDAMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_POLYGON) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_POLYGON;
+ CHECK_DMA_BUFFER(gmesa, 2);
+ WRITEF(gmesa->buf, PolygonOffsetBias, gmesa->glCtx->Polygon.OffsetUnits);
+ WRITEF(gmesa->buf, PolygonOffsetFactor, gmesa->glCtx->Polygon.OffsetFactor);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_STIPPLE) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_STIPPLE;
+ CHECK_DMA_BUFFER(gmesa, 33);
+ WRITE(gmesa->buf, AreaStippleMode, gmesa->AreaStippleMode);
+ WRITE(gmesa->buf, AreaStipplePattern0, gmesa->glCtx->PolygonStipple[0]);
+ WRITE(gmesa->buf, AreaStipplePattern1, gmesa->glCtx->PolygonStipple[1]);
+ WRITE(gmesa->buf, AreaStipplePattern2, gmesa->glCtx->PolygonStipple[2]);
+ WRITE(gmesa->buf, AreaStipplePattern3, gmesa->glCtx->PolygonStipple[3]);
+ WRITE(gmesa->buf, AreaStipplePattern4, gmesa->glCtx->PolygonStipple[4]);
+ WRITE(gmesa->buf, AreaStipplePattern5, gmesa->glCtx->PolygonStipple[5]);
+ WRITE(gmesa->buf, AreaStipplePattern6, gmesa->glCtx->PolygonStipple[6]);
+ WRITE(gmesa->buf, AreaStipplePattern7, gmesa->glCtx->PolygonStipple[7]);
+ WRITE(gmesa->buf, AreaStipplePattern8, gmesa->glCtx->PolygonStipple[8]);
+ WRITE(gmesa->buf, AreaStipplePattern9, gmesa->glCtx->PolygonStipple[9]);
+ WRITE(gmesa->buf, AreaStipplePattern10, gmesa->glCtx->PolygonStipple[10]);
+ WRITE(gmesa->buf, AreaStipplePattern11, gmesa->glCtx->PolygonStipple[11]);
+ WRITE(gmesa->buf, AreaStipplePattern12, gmesa->glCtx->PolygonStipple[12]);
+ WRITE(gmesa->buf, AreaStipplePattern13, gmesa->glCtx->PolygonStipple[13]);
+ WRITE(gmesa->buf, AreaStipplePattern14, gmesa->glCtx->PolygonStipple[14]);
+ WRITE(gmesa->buf, AreaStipplePattern15, gmesa->glCtx->PolygonStipple[15]);
+ WRITE(gmesa->buf, AreaStipplePattern16, gmesa->glCtx->PolygonStipple[16]);
+ WRITE(gmesa->buf, AreaStipplePattern17, gmesa->glCtx->PolygonStipple[17]);
+ WRITE(gmesa->buf, AreaStipplePattern18, gmesa->glCtx->PolygonStipple[18]);
+ WRITE(gmesa->buf, AreaStipplePattern19, gmesa->glCtx->PolygonStipple[19]);
+ WRITE(gmesa->buf, AreaStipplePattern20, gmesa->glCtx->PolygonStipple[20]);
+ WRITE(gmesa->buf, AreaStipplePattern21, gmesa->glCtx->PolygonStipple[21]);
+ WRITE(gmesa->buf, AreaStipplePattern22, gmesa->glCtx->PolygonStipple[22]);
+ WRITE(gmesa->buf, AreaStipplePattern23, gmesa->glCtx->PolygonStipple[23]);
+ WRITE(gmesa->buf, AreaStipplePattern24, gmesa->glCtx->PolygonStipple[24]);
+ WRITE(gmesa->buf, AreaStipplePattern25, gmesa->glCtx->PolygonStipple[25]);
+ WRITE(gmesa->buf, AreaStipplePattern26, gmesa->glCtx->PolygonStipple[26]);
+ WRITE(gmesa->buf, AreaStipplePattern27, gmesa->glCtx->PolygonStipple[27]);
+ WRITE(gmesa->buf, AreaStipplePattern28, gmesa->glCtx->PolygonStipple[28]);
+ WRITE(gmesa->buf, AreaStipplePattern29, gmesa->glCtx->PolygonStipple[29]);
+ WRITE(gmesa->buf, AreaStipplePattern30, gmesa->glCtx->PolygonStipple[30]);
+ WRITE(gmesa->buf, AreaStipplePattern31, gmesa->glCtx->PolygonStipple[31]);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_DEPTH) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_DEPTH;
+ CHECK_DMA_BUFFER(gmesa, 4);
+ WRITE(gmesa->buf, DepthMode, gmesa->DepthMode);
+ WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode);
+ WRITE(gmesa->buf, GLINTWindow,gmesa->Window | (gmesa->FrameCount << 9));
+ WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_GEOMETRY) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_GEOMETRY;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, GeometryMode, gmesa->GeometryMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_TRANSFORM) {
+ gmesa->dirty &= ~GAMMA_UPLOAD_TRANSFORM;
+ CHECK_DMA_BUFFER(gmesa, 1);
+ WRITE(gmesa->buf, TransformMode, gmesa->TransformMode);
+ }
+ if (gmesa->dirty & GAMMA_UPLOAD_TEX0) {
+ gammaTextureObjectPtr curTex = gmesa->CurrentTexObj[0];
+ gmesa->dirty &= ~GAMMA_UPLOAD_TEX0;
+ if (curTex) {
+ CHECK_DMA_BUFFER(gmesa, 21);
+ WRITE(gmesa->buf, GeometryMode, gmesa->GeometryMode | GM_TextureEnable);
+ WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode | DM_TextureEnable);
+ WRITE(gmesa->buf, TextureAddressMode, curTex->TextureAddressMode);
+ WRITE(gmesa->buf, TextureReadMode, curTex->TextureReadMode);
+ WRITE(gmesa->buf, TextureColorMode, curTex->TextureColorMode);
+ WRITE(gmesa->buf, TextureFilterMode, curTex->TextureFilterMode);
+ WRITE(gmesa->buf, TextureFormat, curTex->TextureFormat);
+ WRITE(gmesa->buf, GLINTBorderColor, curTex->TextureBorderColor);
+ WRITE(gmesa->buf, TxBaseAddr0, curTex->TextureBaseAddr[0]);
+ WRITE(gmesa->buf, TxBaseAddr1, curTex->TextureBaseAddr[1]);
+ WRITE(gmesa->buf, TxBaseAddr2, curTex->TextureBaseAddr[2]);
+ WRITE(gmesa->buf, TxBaseAddr3, curTex->TextureBaseAddr[3]);
+ WRITE(gmesa->buf, TxBaseAddr4, curTex->TextureBaseAddr[4]);
+ WRITE(gmesa->buf, TxBaseAddr5, curTex->TextureBaseAddr[5]);
+ WRITE(gmesa->buf, TxBaseAddr6, curTex->TextureBaseAddr[6]);
+ WRITE(gmesa->buf, TxBaseAddr7, curTex->TextureBaseAddr[7]);
+ WRITE(gmesa->buf, TxBaseAddr8, curTex->TextureBaseAddr[8]);
+ WRITE(gmesa->buf, TxBaseAddr9, curTex->TextureBaseAddr[9]);
+ WRITE(gmesa->buf, TxBaseAddr10, curTex->TextureBaseAddr[10]);
+ WRITE(gmesa->buf, TxBaseAddr11, curTex->TextureBaseAddr[11]);
+ WRITE(gmesa->buf, TxBaseAddr12, curTex->TextureBaseAddr[12]);
+ WRITE(gmesa->buf, TextureCacheControl, (TCC_Enable | TCC_Invalidate));
+ } else {
+ CHECK_DMA_BUFFER(gmesa, 6);
+ WRITE(gmesa->buf, GeometryMode, gmesa->GeometryMode);
+ WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode);
+ WRITE(gmesa->buf, TextureAddressMode, TextureAddressModeDisable);
+ WRITE(gmesa->buf, TextureReadMode, TextureReadModeDisable);
+ WRITE(gmesa->buf, TextureFilterMode, TextureFilterModeDisable);
+ WRITE(gmesa->buf, TextureColorMode, TextureColorModeDisable);
+ }
+ }
+#ifdef DO_VALIDATE
+ PROCESS_DMA_BUFFER_TOP_HALF(gmesa);
+
+ DRM_SPINUNLOCK(&gmesa->driScreen->pSAREA->drawable_lock,
+ gmesa->driScreen->drawLockID);
+ VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa);
+
+ PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa);
+#endif
+}
+
+void gammaDDUpdateHWState( GLcontext *ctx )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ int new_state = gmesa->new_state;
+
+ if ( new_state )
+ {
+ FLUSH_BATCH( gmesa );
+
+ gmesa->new_state = 0;
+
+ /* Update the various parts of the context's state.
+ */
+ if ( new_state & GAMMA_NEW_ALPHA )
+ gammaUpdateAlphaMode( ctx );
+
+ if ( new_state & GAMMA_NEW_DEPTH )
+ gammaUpdateZMode( ctx );
+
+ if ( new_state & GAMMA_NEW_FOG )
+ gammaUpdateFogAttrib( ctx );
+
+ if ( new_state & GAMMA_NEW_CLIP )
+ gammaUpdateClipping( ctx );
+
+ if ( new_state & GAMMA_NEW_POLYGON )
+ gammaUpdatePolygon( ctx );
+
+ if ( new_state & GAMMA_NEW_CULL )
+ gammaUpdateCull( ctx );
+
+ if ( new_state & GAMMA_NEW_MASKS )
+ gammaUpdateMasks( ctx );
+
+ if ( new_state & GAMMA_NEW_WINDOW )
+ gammaUpdateWindow( ctx );
+
+ if ( new_state & GAMMA_NEW_STIPPLE )
+ gammaUpdateStipple( ctx );
+ }
+
+ /* HACK ! */
+
+ gammaEmitHwState( gmesa );
+}
+
+
+static void gammaDDUpdateState( 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 );
+ GAMMA_CONTEXT(ctx)->new_gl_state |= new_state;
+}
+
+
+/* Initialize the context's hardware state.
+ */
+void gammaDDInitState( gammaContextPtr gmesa )
+{
+ gmesa->new_state = 0;
+}
+
+/* Initialize the driver's state functions.
+ */
+void gammaDDInitStateFuncs( GLcontext *ctx )
+{
+ ctx->Driver.UpdateState = gammaDDUpdateState;
+
+ ctx->Driver.Clear = gammaDDClear;
+ ctx->Driver.ClearIndex = NULL;
+ ctx->Driver.ClearColor = gammaDDClearColor;
+ ctx->Driver.DrawBuffer = gammaDDDrawBuffer;
+ ctx->Driver.ReadBuffer = gammaDDReadBuffer;
+
+ ctx->Driver.IndexMask = NULL;
+ ctx->Driver.ColorMask = gammaDDColorMask;
+
+ ctx->Driver.AlphaFunc = gammaDDAlphaFunc;
+ ctx->Driver.BlendEquation = gammaDDBlendEquation;
+ ctx->Driver.BlendFunc = gammaDDBlendFunc;
+ ctx->Driver.BlendFuncSeparate = gammaDDBlendFuncSeparate;
+ ctx->Driver.ClearDepth = gammaDDClearDepth;
+ ctx->Driver.CullFace = gammaDDCullFace;
+ ctx->Driver.FrontFace = gammaDDFrontFace;
+ ctx->Driver.DepthFunc = gammaDDDepthFunc;
+ ctx->Driver.DepthMask = gammaDDDepthMask;
+ ctx->Driver.DepthRange = gammaDDDepthRange;
+ ctx->Driver.Enable = gammaDDEnable;
+ ctx->Driver.Finish = gammaDDFinish;
+ ctx->Driver.Flush = gammaDDFlush;
+#if 0
+ ctx->Driver.Fogfv = gammaDDFogfv;
+#endif
+ ctx->Driver.Hint = NULL;
+ ctx->Driver.LineWidth = gammaDDLineWidth;
+ ctx->Driver.LineStipple = gammaDDLineStipple;
+#if ENABLELIGHTING
+ ctx->Driver.Lightfv = gammaDDLightfv;
+ ctx->Driver.LightModelfv = gammaDDLightModelfv;
+#endif
+ ctx->Driver.LogicOpcode = gammaDDLogicalOpcode;
+ ctx->Driver.PointSize = gammaDDPointSize;
+ ctx->Driver.PolygonMode = gammaDDPolygonMode;
+ ctx->Driver.PolygonStipple = gammaDDPolygonStipple;
+ ctx->Driver.Scissor = gammaDDScissor;
+ ctx->Driver.ShadeModel = gammaDDShadeModel;
+ ctx->Driver.ClearStencil = NULL;
+ ctx->Driver.StencilFunc = NULL;
+ ctx->Driver.StencilMask = NULL;
+ ctx->Driver.StencilOp = NULL;
+ ctx->Driver.Viewport = gammaDDViewport;
+}