OSDN Git Service

Remove CVS keywords.
[android-x86/external-mesa.git] / src / mesa / drivers / dri / gamma / gamma_state.c
1 /*
2  * Copyright 2001 by Alan Hourihane.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of Alan Hourihane not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission.  Alan Hourihane makes no representations
11  * about the suitability of this software for any purpose.  It is provided
12  * "as is" without express or implied warranty.
13  *
14  * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  *
22  * Authors:  Alan Hourihane, <alanh@tungstengraphics.com>
23  *
24  * 3DLabs Gamma driver
25  */
26
27 #include "gamma_context.h"
28 #include "gamma_macros.h"
29 #include "buffers.h"
30 #include "macros.h"
31 #include "glint_dri.h"
32 #include "colormac.h"
33 #include "swrast/swrast.h"
34 #include "swrast_setup/swrast_setup.h"
35 #include "vbo/vbo.h"
36 #include "tnl/tnl.h"
37
38 #define ENABLELIGHTING 0
39
40 /* =============================================================
41  * Alpha blending
42  */
43
44 static void gammaUpdateAlphaMode( GLcontext *ctx )
45 {
46    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
47    u_int32_t a = gmesa->AlphaTestMode;
48    u_int32_t b = gmesa->AlphaBlendMode;
49    u_int32_t f = gmesa->AB_FBReadMode_Save = 0;
50    GLubyte refByte = (GLint) (ctx->Color.AlphaRef * 255.0);
51
52    a &= ~(AT_CompareMask | AT_RefValueMask);
53    b &= ~(AB_SrcBlendMask | AB_DstBlendMask);
54
55    a |= refByte << 4;
56
57    switch ( ctx->Color.AlphaFunc ) {
58       case GL_NEVER:
59          a |= AT_Never;
60          break;
61       case GL_LESS:
62          a |= AT_Less;
63          break;
64       case GL_EQUAL:
65          a |= AT_Equal;
66          break;
67       case GL_LEQUAL:
68          a |= AT_LessEqual;
69          break;
70       case GL_GEQUAL:
71          a |= AT_GreaterEqual;
72          break;
73       case GL_GREATER:
74          a |= AT_Greater;
75          break;
76       case GL_NOTEQUAL:
77          a |= AT_NotEqual;
78          break;
79       case GL_ALWAYS:
80          a |= AT_Always;
81          break;
82    }
83
84    if ( ctx->Color.AlphaEnabled ) {
85       f |= FBReadDstEnable;
86       a |= AlphaTestModeEnable;
87    } else {
88       a &= ~AlphaTestModeEnable;
89    }
90
91    switch ( ctx->Color.BlendSrcRGB ) {
92       case GL_ZERO:
93          b |= AB_Src_Zero; 
94          break;
95       case GL_ONE:
96          b |= AB_Src_One;
97          break;
98       case GL_DST_COLOR:
99          b |= AB_Src_DstColor;
100          break;
101       case GL_ONE_MINUS_DST_COLOR:
102          b |= AB_Src_OneMinusDstColor;
103          break;
104       case GL_SRC_ALPHA:
105          b |= AB_Src_SrcAlpha;
106          break;
107       case GL_ONE_MINUS_SRC_ALPHA:
108          b |= AB_Src_OneMinusSrcAlpha;
109          break;
110       case GL_DST_ALPHA:
111          b |= AB_Src_DstAlpha;
112          f |= FBReadSrcEnable;
113          break;
114       case GL_ONE_MINUS_DST_ALPHA:
115          b |= AB_Src_OneMinusDstAlpha;
116          f |= FBReadSrcEnable;
117          break;
118       case GL_SRC_ALPHA_SATURATE:
119          b |= AB_Src_SrcAlphaSaturate;
120          break;
121    }
122
123    switch ( ctx->Color.BlendDstRGB ) {
124       case GL_ZERO:
125          b |= AB_Dst_Zero;
126          break;
127       case GL_ONE:
128          b |= AB_Dst_One;
129          break;
130       case GL_SRC_COLOR:
131          b |= AB_Dst_SrcColor;
132          break;
133       case GL_ONE_MINUS_SRC_COLOR:
134          b |= AB_Dst_OneMinusSrcColor;
135          break;
136       case GL_SRC_ALPHA:
137          b |= AB_Dst_SrcAlpha;
138          break;
139       case GL_ONE_MINUS_SRC_ALPHA:
140          b |= AB_Dst_OneMinusSrcAlpha;
141          break;
142       case GL_DST_ALPHA:
143          b |= AB_Dst_DstAlpha;
144          f |= FBReadSrcEnable;
145          break;
146       case GL_ONE_MINUS_DST_ALPHA:
147          b |= AB_Dst_OneMinusDstAlpha;
148          f |= FBReadSrcEnable;
149          break;
150    }
151
152    if ( ctx->Color.BlendEnabled ) {
153       f |= FBReadDstEnable;
154       b |= AlphaBlendModeEnable;
155    } else {
156       b &= ~AlphaBlendModeEnable;
157    }
158
159    if ( gmesa->AlphaTestMode != a ) {
160       gmesa->AlphaTestMode = a;
161       gmesa->dirty |= GAMMA_UPLOAD_ALPHA;
162    }
163    if ( gmesa->AlphaBlendMode != b) {
164       gmesa->AlphaBlendMode = b;
165       gmesa->dirty |= GAMMA_UPLOAD_BLEND;
166    }
167    gmesa->AB_FBReadMode_Save = f;
168 }
169
170 static void gammaDDAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
171 {
172    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
173    (void) ref;
174
175    FLUSH_BATCH( gmesa );
176
177    gmesa->new_state |= GAMMA_NEW_ALPHA;
178 }
179
180 static void gammaDDBlendEquationSeparate( GLcontext *ctx, 
181                                           GLenum modeRGB, GLenum modeA )
182 {
183    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
184
185    assert( modeRGB == modeA );
186    FLUSH_BATCH( gmesa );
187
188    gmesa->new_state |= GAMMA_NEW_ALPHA;
189 }
190
191 static void gammaDDBlendFuncSeparate( GLcontext *ctx,
192                                      GLenum sfactorRGB, GLenum dfactorRGB,
193                                      GLenum sfactorA, GLenum dfactorA )
194 {
195    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
196
197    FLUSH_BATCH( gmesa );
198
199    gmesa->new_state |= GAMMA_NEW_ALPHA;
200 }
201
202
203 /* ================================================================
204  * Buffer clear
205  */
206
207 static void gammaDDClear( GLcontext *ctx, GLbitfield mask )
208 {
209    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
210    GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)gmesa->driScreen->pDevPriv;
211    GLuint temp = 0;
212
213    FLUSH_BATCH( gmesa );
214
215    /* Update and emit any new state.  We need to do this here to catch
216     * changes to the masks.
217     * FIXME: Just update the masks?
218     */
219    if ( gmesa->new_state )
220       gammaDDUpdateHWState( ctx );
221
222 #ifdef DO_VALIDATE
223     /* Flush any partially filled buffers */
224     FLUSH_DMA_BUFFER(gmesa);
225
226     DRM_SPINLOCK(&gmesa->driScreen->pSAREA->drawable_lock,
227                  gmesa->driScreen->drawLockID);
228     VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa);
229 #endif
230
231     if (mask & BUFFER_BIT_DEPTH) {
232          /* Turn off writes the FB */
233          CHECK_DMA_BUFFER(gmesa, 1);
234          WRITE(gmesa->buf, FBWriteMode, FBWriteModeDisable);
235
236          mask &= ~BUFFER_BIT_DEPTH;
237
238          /*
239           * Turn Rectangle2DControl off when the window is not clipped
240           * (i.e., the GID tests are not necessary).  This dramatically
241           * increases the performance of the depth clears.
242           */
243          if (!gmesa->NotClipped) {
244             CHECK_DMA_BUFFER(gmesa, 1);
245             WRITE(gmesa->buf, Rectangle2DControl, 1);
246          }
247
248          temp = (gmesa->LBReadMode & LBPartialProdMask) | LBWindowOriginBot;
249          if (gDRIPriv->numMultiDevices == 2) temp |= LBScanLineInt2;
250          
251          CHECK_DMA_BUFFER(gmesa, 5);
252          WRITE(gmesa->buf, LBReadMode, temp);
253          WRITE(gmesa->buf, DeltaMode, DM_DepthEnable);
254          WRITE(gmesa->buf, DepthMode, (DepthModeEnable |
255                                         DM_Always |
256                                         DM_SourceDepthRegister |
257                                         DM_WriteMask));
258          WRITE(gmesa->buf, GLINTDepth, gmesa->ClearDepth);
259
260          /* Increment the frame count */
261          gmesa->FrameCount++;
262 #ifdef FAST_CLEAR_4
263          gmesa->FrameCount &= 0x0f;
264 #else
265          gmesa->FrameCount &= 0xff;
266 #endif
267
268          /* Force FCP to be written */
269          WRITE(gmesa->buf, GLINTWindow, (WindowEnable |
270                                           W_PassIfEqual |
271                                           (gmesa->Window & W_GIDMask) |
272                                           W_DepthFCP |
273                                           W_LBUpdateFromRegisters |
274                                           W_OverrideWriteFiltering |
275                                           (gmesa->FrameCount << 9)));
276
277         /* Clear part of the depth and FCP buffers */
278         {
279             int y = gmesa->driScreen->fbHeight - gmesa->driDrawable->y - gmesa->driDrawable->h;
280             int x = gmesa->driDrawable->x;
281             int w = gmesa->driDrawable->w;
282             int h = gmesa->driDrawable->h;
283 #ifndef TURN_OFF_FCP
284             float hsub = h;
285
286             if (gmesa->WindowChanged) {
287                 gmesa->WindowChanged = GL_FALSE;
288             } else {
289 #ifdef FAST_CLEAR_4
290                 hsub /= 16;
291 #else
292                 hsub /= 256;
293 #endif
294
295                 /* Handle the case where the height < # of FCPs */
296                 if (hsub < 1.0) {
297                     if (gmesa->FrameCount > h)
298                         gmesa->FrameCount = 0;
299                     h = 1;
300                     y += gmesa->FrameCount;
301                 } else {
302                     h = (gmesa->FrameCount+1)*hsub;
303                     h -= (int)(gmesa->FrameCount*hsub);
304                     y += gmesa->FrameCount*hsub;
305                 }
306             }
307 #endif
308             if (h && w) {
309 #if 0
310                 CHECK_DMA_BUFFER(gmesa, 2);
311                 WRITE(gmesa->buf, Rectangle2DMode, ((h & 0xfff)<<12) |
312                                                    (w & 0xfff) );
313                 WRITE(gmesa->buf, DrawRectangle2D, ((y & 0xffff)<<16) |
314                                                    (x & 0xffff) );
315 #else
316                 CHECK_DMA_BUFFER(gmesa, 8);
317                 WRITE(gmesa->buf, StartXDom,   x<<16);
318                 WRITE(gmesa->buf, StartY,      y<<16);
319                 WRITE(gmesa->buf, StartXSub,   (x+w)<<16);
320                 WRITE(gmesa->buf, GLINTCount,  h);
321                 WRITE(gmesa->buf, dY,          1<<16);
322                 WRITE(gmesa->buf, dXDom,       0<<16);
323                 WRITE(gmesa->buf, dXSub,       0<<16);
324                 WRITE(gmesa->buf, Render,      0x00000040); /* NOT_DONE */
325 #endif
326             }
327         }
328
329         CHECK_DMA_BUFFER(gmesa, 6);
330         WRITE(gmesa->buf, DepthMode, gmesa->DepthMode);
331         WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode);
332         WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode);
333         WRITE(gmesa->buf, GLINTWindow, gmesa->Window);
334         WRITE(gmesa->buf, FastClearDepth, gmesa->ClearDepth);
335         WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable);
336
337         /* Turn on Depth FCP */
338         if (gmesa->Window & W_DepthFCP) {
339             CHECK_DMA_BUFFER(gmesa, 1);
340             WRITE(gmesa->buf, WindowOr, (gmesa->FrameCount << 9));
341         }
342
343         /* Turn off GID clipping if window is not clipped */
344         if (gmesa->NotClipped) {
345             CHECK_DMA_BUFFER(gmesa, 1);
346             WRITE(gmesa->buf, Rectangle2DControl, 0);
347         }
348     }
349
350     if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT)) {
351         int y = gmesa->driScreen->fbHeight - gmesa->driDrawable->y - gmesa->driDrawable->h;
352         int x = gmesa->driDrawable->x;
353         int w = gmesa->driDrawable->w;
354         int h = gmesa->driDrawable->h;
355
356         mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
357
358         if (x < 0) { w -= -x; x = 0; }
359
360         /* Turn on GID clipping if window is clipped */
361         if (!gmesa->NotClipped) {
362             CHECK_DMA_BUFFER(gmesa, 1);
363             WRITE(gmesa->buf, Rectangle2DControl, 1);
364         }
365
366         CHECK_DMA_BUFFER(gmesa, 18);
367         WRITE(gmesa->buf, FBBlockColor, gmesa->ClearColor);
368         WRITE(gmesa->buf, ColorDDAMode, ColorDDADisable);
369         WRITE(gmesa->buf, FBWriteMode, FBWriteModeEnable);
370         WRITE(gmesa->buf, DepthMode, 0);
371         WRITE(gmesa->buf, DeltaMode, 0);
372         WRITE(gmesa->buf, AlphaBlendMode, 0);
373 #if 1
374         WRITE(gmesa->buf, dY,          1<<16);
375         WRITE(gmesa->buf, dXDom,       0<<16);
376         WRITE(gmesa->buf, dXSub,       0<<16);
377         WRITE(gmesa->buf, StartXSub,   (x+w)<<16);
378         WRITE(gmesa->buf, GLINTCount,  h);
379         WRITE(gmesa->buf, StartXDom,   x<<16);
380         WRITE(gmesa->buf, StartY,      y<<16);
381         WRITE(gmesa->buf, Render,      0x00000048); /* NOT_DONE */
382 #else
383         WRITE(gmesa->buf, Rectangle2DMode, (((h & 0xfff)<<12) |
384                                               (w & 0xfff)));
385         WRITE(gmesa->buf, DrawRectangle2D, (((y & 0xffff)<<16) |
386                                               (x & 0xffff)));
387 #endif
388         WRITE(gmesa->buf, DepthMode, gmesa->DepthMode);
389         WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode);
390         WRITE(gmesa->buf, AlphaBlendMode, gmesa->AlphaBlendMode);
391         WRITE(gmesa->buf, ColorDDAMode, gmesa->ColorDDAMode);
392
393         /* Turn off GID clipping if window is clipped */
394         if (gmesa->NotClipped) {
395             CHECK_DMA_BUFFER(gmesa, 1);
396             WRITE(gmesa->buf, Rectangle2DControl, 0);
397         }
398     }
399
400 #ifdef DO_VALIDATE
401     PROCESS_DMA_BUFFER_TOP_HALF(gmesa);
402
403     DRM_SPINUNLOCK(&gmesa->driScreen->pSAREA->drawable_lock,
404                    gmesa->driScreen->drawLockID);
405     VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa);
406
407     PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa);
408 #endif
409
410    if ( mask )
411       _swrast_Clear( ctx, mask );
412 }
413
414 /* =============================================================
415  * Depth testing
416  */
417
418 static void gammaUpdateZMode( GLcontext *ctx )
419 {
420    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
421    u_int32_t z = gmesa->DepthMode;
422    u_int32_t delta = gmesa->DeltaMode;
423    u_int32_t window = gmesa->Window;
424    u_int32_t lbread = gmesa->LBReadMode;
425
426    z &= ~DM_CompareMask;
427
428    switch ( ctx->Depth.Func ) {
429       case GL_NEVER:
430          z |= DM_Never;
431          break;
432       case GL_ALWAYS:
433          z |= DM_Always;
434          break;
435       case GL_LESS:
436          z |= DM_Less;
437          break;
438       case GL_LEQUAL:
439          z |= DM_LessEqual;
440          break;
441       case GL_EQUAL:
442          z |= DM_Equal;
443          break;
444       case GL_GEQUAL:
445          z |= DM_GreaterEqual;
446          break;
447       case GL_GREATER:
448          z |= DM_Greater;
449          break;
450       case GL_NOTEQUAL:
451          z |= DM_NotEqual;
452          break;
453    }
454
455    if ( ctx->Depth.Test ) {
456       z      |= DepthModeEnable;
457       delta  |= DM_DepthEnable;
458       window |= W_DepthFCP;
459       lbread |= LBReadDstEnable;
460    } else {
461       z      &= ~DepthModeEnable;
462       delta  &= ~DM_DepthEnable;
463       window &= ~W_DepthFCP;
464       lbread &= ~LBReadDstEnable;
465    }
466
467    if ( ctx->Depth.Mask ) {
468       z |= DM_WriteMask;
469    } else {
470       z &= ~DM_WriteMask;
471    }
472
473 #if 0
474    if ( gmesa->DepthMode != z ){
475 #endif
476       gmesa->DepthMode = z;
477       gmesa->DeltaMode = delta;
478       gmesa->Window = window;
479       gmesa->LBReadMode = lbread;
480       gmesa->dirty |= GAMMA_UPLOAD_DEPTH;
481 #if 0
482    }
483 #endif
484 }
485
486 static void gammaDDDepthFunc( GLcontext *ctx, GLenum func )
487 {
488    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
489
490    FLUSH_BATCH( gmesa );
491    gmesa->new_state |= GAMMA_NEW_DEPTH;
492 }
493
494 static void gammaDDDepthMask( GLcontext *ctx, GLboolean flag )
495 {
496    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
497
498    FLUSH_BATCH( gmesa );
499    gmesa->new_state |= GAMMA_NEW_DEPTH;
500 }
501
502 static void gammaDDClearDepth( GLcontext *ctx, GLclampd d )
503 {
504    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
505
506    switch ( gmesa->DepthSize ) {
507    case 16:
508       gmesa->ClearDepth = d * 0x0000ffff;
509       break;
510    case 24:
511       gmesa->ClearDepth = d * 0x00ffffff;
512       break;
513    case 32:
514       gmesa->ClearDepth = d * 0xffffffff;
515       break;
516    }
517 }
518
519 static void gammaDDFinish( GLcontext *ctx )
520 {
521    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
522
523    FLUSH_DMA_BUFFER(gmesa);
524 }
525
526 static void gammaDDFlush( GLcontext *ctx )
527 {
528    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
529
530    FLUSH_DMA_BUFFER(gmesa);
531 }
532
533 /* =============================================================
534  * Fog
535  */
536
537 static void gammaUpdateFogAttrib( GLcontext *ctx )
538 {
539    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
540    u_int32_t f = gmesa->FogMode;
541    u_int32_t g = gmesa->GeometryMode;
542    u_int32_t d = gmesa->DeltaMode;
543
544    if (ctx->Fog.Enabled) {
545       f |= FogModeEnable;
546       g |= GM_FogEnable;
547       d |= DM_FogEnable;
548    } else {
549       f &= ~FogModeEnable;
550       g &= ~GM_FogEnable;
551       d &= ~DM_FogEnable;
552    }
553
554    g &= ~GM_FogMask;
555
556    switch (ctx->Fog.Mode) {
557       case GL_LINEAR:
558          g |= GM_FogLinear;
559          break;
560       case GL_EXP:
561          g |= GM_FogExp;
562          break;
563       case GL_EXP2:
564          g |= GM_FogExpSquared;
565          break;
566    }
567
568    if ( gmesa->FogMode != f ) {
569       gmesa->FogMode = f;
570       gmesa->dirty |= GAMMA_UPLOAD_FOG;
571    }
572  
573    if ( gmesa->GeometryMode != g ) {
574       gmesa->GeometryMode = g;
575       gmesa->dirty |= GAMMA_UPLOAD_GEOMETRY;
576    }
577
578    if ( gmesa->DeltaMode != d ) {
579       gmesa->DeltaMode = d;
580       gmesa->dirty |= GAMMA_UPLOAD_DEPTH;
581    }
582 }
583
584 #if 0
585 static void gammaDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
586 {
587    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
588
589    FLUSH_BATCH( gmesa );
590    gmesa->new_state |= GAMMA_NEW_FOG;
591 }
592 #endif
593
594 /* =============================================================
595  * Lines
596  */
597 static void gammaDDLineWidth( GLcontext *ctx, GLfloat width )
598 {
599    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
600
601    CHECK_DMA_BUFFER(gmesa, 3);
602    WRITE(gmesa->buf, LineWidth, (GLuint)width);
603    WRITEF(gmesa->buf, AAlineWidth, width);
604    WRITE(gmesa->buf, LineWidthOffset, (GLuint)(width-1)/2);
605 }
606
607 static void gammaDDLineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
608 {
609    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
610
611    gmesa->LineMode &= ~(LM_StippleMask | LM_RepeatFactorMask);
612    gmesa->LineMode |= ((GLuint)(factor - 1) << 1) | ((GLuint)pattern << 10); 
613
614    gmesa->dirty |= GAMMA_UPLOAD_LINEMODE;
615 }
616
617
618
619 /* =============================================================
620  * Points
621  */
622 static void gammaDDPointSize( GLcontext *ctx, GLfloat size )
623 {
624    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
625
626    CHECK_DMA_BUFFER(gmesa, 2);
627    WRITE(gmesa->buf, PointSize, (GLuint)size);
628    WRITEF(gmesa->buf, AApointSize, size);
629 }
630
631 /* =============================================================
632  * Polygon 
633  */
634
635 static void gammaUpdatePolygon( GLcontext *ctx )
636 {
637    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
638    u_int32_t g = gmesa->GeometryMode;
639
640    g &= ~(GM_PolyOffsetFillEnable | GM_PolyOffsetPointEnable |
641           GM_PolyOffsetLineEnable);
642
643    if (ctx->Polygon.OffsetFill) g |= GM_PolyOffsetFillEnable;
644    if (ctx->Polygon.OffsetPoint) g |= GM_PolyOffsetPointEnable;
645    if (ctx->Polygon.OffsetLine) g |= GM_PolyOffsetLineEnable;
646
647    g &= ~GM_FB_PolyMask;
648
649    switch (ctx->Polygon.FrontMode) {
650       case GL_FILL:
651          g |= GM_FrontPolyFill;
652          break;
653       case GL_LINE:
654          g |= GM_FrontPolyLine;
655          break;
656       case GL_POINT:
657          g |= GM_FrontPolyPoint;
658          break;
659    }
660
661    switch (ctx->Polygon.BackMode) {
662       case GL_FILL:
663          g |= GM_BackPolyFill;
664          break;
665       case GL_LINE:
666          g |= GM_BackPolyLine;
667          break;
668       case GL_POINT:
669          g |= GM_BackPolyPoint;
670          break;
671    }
672
673    if ( gmesa->GeometryMode != g ) {
674       gmesa->GeometryMode = g;
675       gmesa->dirty |= GAMMA_UPLOAD_GEOMETRY;
676    }
677
678    gmesa->dirty |= GAMMA_UPLOAD_POLYGON;
679 }
680
681 static void gammaDDPolygonMode( GLcontext *ctx, GLenum face, GLenum mode)
682 {
683    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
684
685    FLUSH_BATCH( gmesa );
686
687    gmesa->new_state |= GAMMA_NEW_POLYGON;
688 }
689
690 static void gammaUpdateStipple( GLcontext *ctx )
691 {
692    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
693
694    FLUSH_BATCH( gmesa );
695
696    if (ctx->Polygon.StippleFlag) {
697       gmesa->AreaStippleMode |= AreaStippleModeEnable/* | ASM_X32 | ASM_Y32*/;
698    } else {
699       gmesa->AreaStippleMode &= ~AreaStippleModeEnable;
700    }
701
702    gmesa->dirty |= GAMMA_UPLOAD_STIPPLE;
703 }
704
705 static void gammaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask)
706 {
707    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
708    FLUSH_BATCH( gmesa );
709    gmesa->new_state |= GAMMA_NEW_STIPPLE;
710 }
711
712 /* =============================================================
713  * Clipping
714  */
715
716 static void gammaUpdateClipping( GLcontext *ctx )
717 {
718    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
719    GLint x1, y1, x2, y2;
720
721    if ( gmesa->driDrawable ) {
722       x1 = gmesa->driDrawable->x + ctx->Scissor.X;
723       y1 = gmesa->driScreen->fbHeight -
724         (gmesa->driDrawable->y +
725          gmesa->driDrawable->h) + ctx->Scissor.Y;
726       x2 = x1 + ctx->Scissor.Width;
727       y2 = y1 + ctx->Scissor.Height;
728
729       gmesa->ScissorMinXY = x1 | (y1 << 16);
730       gmesa->ScissorMaxXY = x2 | (y2 << 16);
731       if (ctx->Scissor.Enabled) 
732          gmesa->ScissorMode |= UserScissorEnable;
733       else
734          gmesa->ScissorMode &= ~UserScissorEnable;
735
736       gmesa->dirty |= GAMMA_UPLOAD_CLIP;
737    }
738 }
739
740 static void gammaDDScissor( GLcontext *ctx,
741                            GLint x, GLint y, GLsizei w, GLsizei h )
742 {
743    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
744
745    FLUSH_BATCH( gmesa );
746    gmesa->new_state |= GAMMA_NEW_CLIP;
747 }
748
749 /* =============================================================
750  * Culling
751  */
752
753 static void gammaUpdateCull( GLcontext *ctx )
754 {
755    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
756    u_int32_t g = gmesa->GeometryMode;
757
758    g &= ~(GM_PolyCullMask | GM_FFMask);
759
760    if (ctx->Polygon.FrontFace == GL_CCW) {
761       g |= GM_FrontFaceCCW;
762    } else {
763       g |= GM_FrontFaceCW;
764    }
765
766    switch ( ctx->Polygon.CullFaceMode ) {
767       case GL_FRONT:
768          g |= GM_PolyCullFront;
769          break;
770       case GL_BACK:
771          g |= GM_PolyCullBack;
772          break;
773       case GL_FRONT_AND_BACK:
774          g |= GM_PolyCullBoth;
775          break;
776    }
777
778    if ( ctx->Polygon.CullFlag ) {
779       g |= GM_PolyCullEnable;
780    } else {
781       g &= ~GM_PolyCullEnable;
782    }
783
784    if ( gmesa->GeometryMode != g ) {
785       gmesa->GeometryMode = g;
786       gmesa->dirty |= GAMMA_UPLOAD_GEOMETRY;
787    }
788 }
789
790 static void gammaDDCullFace( GLcontext *ctx, GLenum mode )
791 {
792    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
793
794    FLUSH_BATCH( gmesa );
795    gmesa->new_state |= GAMMA_NEW_CULL;
796 }
797
798 static void gammaDDFrontFace( GLcontext *ctx, GLenum mode )
799 {
800    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
801
802    FLUSH_BATCH( gmesa );
803    gmesa->new_state |= GAMMA_NEW_CULL;
804 }
805
806 /* =============================================================
807  * Masks
808  */
809
810 static void gammaUpdateMasks( GLcontext *ctx )
811 {
812    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
813
814
815    GLuint mask = gammaPackColor( gmesa->gammaScreen->cpp,
816                                 ctx->Color.ColorMask[RCOMP],
817                                 ctx->Color.ColorMask[GCOMP],
818                                 ctx->Color.ColorMask[BCOMP],
819                                 ctx->Color.ColorMask[ACOMP] );
820
821    if (gmesa->gammaScreen->cpp == 2) mask |= mask << 16;
822
823    if ( gmesa->FBHardwareWriteMask != mask ) {
824       gmesa->FBHardwareWriteMask = mask;
825       gmesa->dirty |= GAMMA_UPLOAD_MASKS;
826    }
827 }
828
829 static void gammaDDColorMask( GLcontext *ctx, GLboolean r, GLboolean g,
830                               GLboolean b, GLboolean a)
831 {
832    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
833
834    FLUSH_BATCH( gmesa );
835    gmesa->new_state |= GAMMA_NEW_MASKS;
836 }
837
838 /* =============================================================
839  * Rendering attributes
840  *
841  * We really don't want to recalculate all this every time we bind a
842  * texture.  These things shouldn't change all that often, so it makes
843  * sense to break them out of the core texture state update routines.
844  */
845
846 #if ENABLELIGHTING
847 static void gammaDDLightfv(GLcontext *ctx, GLenum light, GLenum pname, 
848                                 const GLfloat *params, GLint nParams)
849 {
850     gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
851     GLfloat l,x,y,z,w;
852
853     switch(light) {
854     case GL_LIGHT0:
855         switch (pname) {
856         case GL_AMBIENT:
857             CHECK_DMA_BUFFER(gmesa, 3);
858             /* We don't do alpha */
859             WRITEF(gmesa->buf, Light0AmbientIntensityBlue, params[2]);
860             WRITEF(gmesa->buf, Light0AmbientIntensityGreen, params[1]);
861             WRITEF(gmesa->buf, Light0AmbientIntensityRed, params[0]);
862             break;
863         case GL_DIFFUSE:
864             CHECK_DMA_BUFFER(gmesa, 3);
865             /* We don't do alpha */
866             WRITEF(gmesa->buf, Light0DiffuseIntensityBlue, params[2]);
867             WRITEF(gmesa->buf, Light0DiffuseIntensityGreen, params[1]);
868             WRITEF(gmesa->buf, Light0DiffuseIntensityRed, params[0]);
869             break;
870         case GL_SPECULAR:
871             CHECK_DMA_BUFFER(gmesa, 3);
872             /* We don't do alpha */
873             WRITEF(gmesa->buf, Light0SpecularIntensityBlue, params[2]);
874             WRITEF(gmesa->buf, Light0SpecularIntensityGreen, params[1]);
875             WRITEF(gmesa->buf, Light0SpecularIntensityRed, params[0]);
876             break;
877         case GL_POSITION:
878             /* Normalize <x,y,z> */
879             x = params[0]; y = params[1]; z = params[2]; w = params[3];
880             l = sqrt(x*x + y*y + z*z + w*w);
881             w /= l;
882             x /= l;
883             y /= l;
884             z /= l;
885             if (params[3] != 0.0) {
886                 gmesa->Light0Mode |= Light0ModeAttenuation;
887                 gmesa->Light0Mode |= Light0ModeLocal;
888             } else {
889                 gmesa->Light0Mode &= ~Light0ModeAttenuation;
890                 gmesa->Light0Mode &= ~Light0ModeLocal;
891             }
892             CHECK_DMA_BUFFER(gmesa, 5);
893             WRITE(gmesa->buf, Light0Mode, gmesa->Light0Mode);
894             WRITEF(gmesa->buf, Light0PositionW, w);
895             WRITEF(gmesa->buf, Light0PositionZ, z);
896             WRITEF(gmesa->buf, Light0PositionY, y);
897             WRITEF(gmesa->buf, Light0PositionX, x);
898             break;
899         case GL_SPOT_DIRECTION:
900             CHECK_DMA_BUFFER(gmesa, 3);
901             /* WRITEF(gmesa->buf, Light0SpotlightDirectionW, params[3]); */
902             WRITEF(gmesa->buf, Light0SpotlightDirectionZ, params[2]);
903             WRITEF(gmesa->buf, Light0SpotlightDirectionY, params[1]);
904             WRITEF(gmesa->buf, Light0SpotlightDirectionX, params[0]);
905             break;
906         case GL_SPOT_EXPONENT:
907             CHECK_DMA_BUFFER(gmesa, 1);
908             WRITEF(gmesa->buf, Light0SpotlightExponent, params[0]);
909             break;
910         case GL_SPOT_CUTOFF:
911             if (params[0] != 180.0) 
912                 gmesa->Light0Mode |= Light0ModeSpotLight;
913             else
914                 gmesa->Light0Mode &= ~Light0ModeSpotLight;
915             CHECK_DMA_BUFFER(gmesa, 2);
916             WRITE(gmesa->buf, Light0Mode, gmesa->Light0Mode);
917             WRITEF(gmesa->buf, Light0CosSpotlightCutoffAngle, cos(params[0]*DEG2RAD));
918             break;
919         case GL_CONSTANT_ATTENUATION:
920             CHECK_DMA_BUFFER(gmesa, 1);
921             WRITEF(gmesa->buf, Light0ConstantAttenuation, params[0]);
922             break;
923         case GL_LINEAR_ATTENUATION:
924             CHECK_DMA_BUFFER(gmesa, 1);
925             WRITEF(gmesa->buf, Light0LinearAttenuation, params[0]);
926             break;
927         case GL_QUADRATIC_ATTENUATION:
928             CHECK_DMA_BUFFER(gmesa, 1);
929             WRITEF(gmesa->buf, Light0QuadraticAttenuation, params[0]);
930             break;
931         }
932         break;
933     }
934 }
935
936 static void gammaDDLightModelfv( GLcontext *ctx, GLenum pname,
937                                 const GLfloat *params )
938 {
939    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
940
941    switch (pname) {
942    case GL_LIGHT_MODEL_AMBIENT:
943         CHECK_DMA_BUFFER(gmesa, 3);
944         /* We don't do alpha */
945         WRITEF(gmesa->buf, SceneAmbientColorBlue, params[2]);
946         WRITEF(gmesa->buf, SceneAmbientColorGreen, params[1]);
947         WRITEF(gmesa->buf, SceneAmbientColorRed, params[0]);
948         break;
949     case GL_LIGHT_MODEL_LOCAL_VIEWER:
950         if (params[0] != 0.0)
951             gmesa->LightingMode |= LightingModeLocalViewer;
952         else
953             gmesa->LightingMode &= ~LightingModeLocalViewer;
954         CHECK_DMA_BUFFER(gmesa, 1);
955         WRITE(gmesa->buf, LightingMode, gmesa->LightingMode);
956         break;
957     case GL_LIGHT_MODEL_TWO_SIDE:
958         if (params[0] == 1.0f) {
959             gmesa->LightingMode |= LightingModeTwoSides;
960             gmesa->MaterialMode |= MaterialModeTwoSides;
961         } else {
962             gmesa->LightingMode &= ~LightingModeTwoSides;
963             gmesa->MaterialMode &= ~MaterialModeTwoSides;
964         }
965         CHECK_DMA_BUFFER(gmesa, 2);
966         WRITE(gmesa->buf, LightingMode, gmesa->LightingMode);
967         WRITE(gmesa->buf, MaterialMode, gmesa->MaterialMode);
968         break;
969     }
970 }
971 #endif
972
973 static void gammaDDShadeModel( GLcontext *ctx, GLenum mode )
974 {
975    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
976    u_int32_t g = gmesa->GeometryMode;
977    u_int32_t c = gmesa->ColorDDAMode;
978
979    g &= ~GM_ShadingMask;
980    c &= ~ColorDDAShadingMask;
981
982    switch ( mode ) {
983    case GL_FLAT:
984       g |= GM_FlatShading;
985       c |= ColorDDAFlat;
986       break;
987    case GL_SMOOTH:
988       g |= GM_GouraudShading;
989       c |= ColorDDAGouraud;
990       break;
991    default:
992       return;
993    }
994
995    if ( gmesa->ColorDDAMode != c ) {
996       FLUSH_BATCH( gmesa );
997       gmesa->ColorDDAMode = c;
998
999       gmesa->dirty |= GAMMA_UPLOAD_SHADE;
1000    }
1001
1002    if ( gmesa->GeometryMode != g ) {
1003       FLUSH_BATCH( gmesa );
1004       gmesa->GeometryMode = g;
1005
1006       gmesa->dirty |= GAMMA_UPLOAD_GEOMETRY;
1007    }
1008 }
1009
1010 /* =============================================================
1011  * Miscellaneous
1012  */
1013
1014 static void gammaDDClearColor( GLcontext *ctx, const GLfloat color[4])
1015 {
1016    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
1017    GLubyte c[4];
1018    UNCLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
1019    UNCLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
1020    UNCLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
1021    UNCLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
1022
1023    gmesa->ClearColor = gammaPackColor( gmesa->gammaScreen->cpp,
1024                                        c[0], c[1], c[2], c[3] );
1025
1026    if (gmesa->gammaScreen->cpp == 2) gmesa->ClearColor |= gmesa->ClearColor<<16;
1027 }
1028
1029
1030 static void gammaDDLogicalOpcode( GLcontext *ctx, GLenum opcode )
1031 {
1032    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
1033
1034    FLUSH_BATCH( gmesa );
1035
1036    if ( ctx->Color.ColorLogicOpEnabled ) {
1037       gmesa->LogicalOpMode = opcode << 1 | LogicalOpModeEnable;
1038    } else {
1039       gmesa->LogicalOpMode = LogicalOpModeDisable;
1040    }
1041
1042    gmesa->dirty |= GAMMA_UPLOAD_LOGICOP;
1043 }
1044
1045 static void gammaDDDrawBuffer( GLcontext *ctx, GLenum mode )
1046 {
1047    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
1048
1049    FLUSH_BATCH( gmesa );
1050
1051    switch ( mode ) {
1052    case GL_FRONT_LEFT:
1053       gmesa->drawOffset = gmesa->readOffset = 0;
1054       break;
1055    case GL_BACK_LEFT:
1056       gmesa->drawOffset = gmesa->readOffset = gmesa->driScreen->fbHeight * gmesa->driScreen->fbWidth * gmesa->gammaScreen->cpp; 
1057       break;
1058    }
1059 }
1060
1061 static void gammaDDReadBuffer( GLcontext *ctx, GLenum mode )
1062 {
1063    /* XXX anything? */
1064 }
1065
1066 /* =============================================================
1067  * Window position and viewport transformation
1068  */
1069
1070 void gammaUpdateWindow( GLcontext *ctx )
1071 {
1072    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
1073    __DRIdrawablePrivate *dPriv = gmesa->driDrawable;
1074    GLfloat xoffset = (GLfloat)dPriv->x;
1075    GLfloat yoffset = gmesa->driScreen->fbHeight - (GLfloat)dPriv->y - dPriv->h;
1076    const GLfloat *v = ctx->Viewport._WindowMap.m;
1077
1078    GLfloat sx = v[MAT_SX];
1079    GLfloat tx = v[MAT_TX] + xoffset;
1080    GLfloat sy = v[MAT_SY];
1081    GLfloat ty = v[MAT_TY] + yoffset;
1082    GLfloat sz = v[MAT_SZ] * gmesa->depth_scale;
1083    GLfloat tz = v[MAT_TZ] * gmesa->depth_scale;
1084
1085    gmesa->dirty |= GAMMA_UPLOAD_VIEWPORT;
1086
1087    gmesa->ViewportScaleX = sx;
1088    gmesa->ViewportScaleY = sy;
1089    gmesa->ViewportScaleZ = sz;
1090    gmesa->ViewportOffsetX = tx;
1091    gmesa->ViewportOffsetY = ty;
1092    gmesa->ViewportOffsetZ = tz;
1093 }
1094
1095
1096
1097 static void gammaDDViewport( GLcontext *ctx, GLint x, GLint y,
1098                             GLsizei width, GLsizei height )
1099 {
1100    gammaUpdateWindow( ctx );
1101 }
1102
1103 static void gammaDDDepthRange( GLcontext *ctx, GLclampd nearval,
1104                               GLclampd farval )
1105 {
1106    gammaUpdateWindow( ctx );
1107 }
1108
1109 void gammaUpdateViewportOffset( GLcontext *ctx )
1110 {
1111    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
1112    __DRIdrawablePrivate *dPriv = gmesa->driDrawable;
1113    GLfloat xoffset = (GLfloat)dPriv->x;
1114    GLfloat yoffset = gmesa->driScreen->fbHeight - (GLfloat)dPriv->y - dPriv->h;
1115    const GLfloat *v = ctx->Viewport._WindowMap.m;
1116
1117    GLfloat tx = v[MAT_TX] + xoffset;
1118    GLfloat ty = v[MAT_TY] + yoffset;
1119
1120    if ( gmesa->ViewportOffsetX != tx ||
1121         gmesa->ViewportOffsetY != ty )
1122    {
1123       gmesa->ViewportOffsetX = tx;
1124       gmesa->ViewportOffsetY = ty;
1125
1126       gmesa->new_state |= GAMMA_NEW_WINDOW;
1127    }
1128
1129    gmesa->new_state |= GAMMA_NEW_CLIP;
1130 }
1131
1132 #if 0
1133 /* 
1134  * Matrix 
1135  */
1136
1137 static void gammaLoadHWMatrix(GLcontext *ctx)
1138 {
1139     gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
1140     const GLfloat *m;
1141
1142     gmesa->TransformMode &= ~XM_XformTexture;
1143
1144     switch (ctx->Transform.MatrixMode) {
1145     case GL_MODELVIEW:
1146         gmesa->TransformMode |= XM_UseModelViewMatrix;
1147         m = ctx->ModelviewMatrixStack.Top->m;
1148         CHECK_DMA_BUFFER(gmesa, 16);
1149         WRITEF(gmesa->buf, ModelViewMatrix0,  m[0]);
1150         WRITEF(gmesa->buf, ModelViewMatrix1,  m[1]);
1151         WRITEF(gmesa->buf, ModelViewMatrix2,  m[2]);
1152         WRITEF(gmesa->buf, ModelViewMatrix3,  m[3]);
1153         WRITEF(gmesa->buf, ModelViewMatrix4,  m[4]);
1154         WRITEF(gmesa->buf, ModelViewMatrix5,  m[5]);
1155         WRITEF(gmesa->buf, ModelViewMatrix6,  m[6]);
1156         WRITEF(gmesa->buf, ModelViewMatrix7,  m[7]);
1157         WRITEF(gmesa->buf, ModelViewMatrix8,  m[8]);
1158         WRITEF(gmesa->buf, ModelViewMatrix9,  m[9]);
1159         WRITEF(gmesa->buf, ModelViewMatrix10, m[10]);
1160         WRITEF(gmesa->buf, ModelViewMatrix11, m[11]);
1161         WRITEF(gmesa->buf, ModelViewMatrix12, m[12]);
1162         WRITEF(gmesa->buf, ModelViewMatrix13, m[13]);
1163         WRITEF(gmesa->buf, ModelViewMatrix14, m[14]);
1164         WRITEF(gmesa->buf, ModelViewMatrix15, m[15]);
1165         break;
1166     case GL_PROJECTION:
1167         m = ctx->ProjectionMatrixStack.Top->m;
1168         CHECK_DMA_BUFFER(gmesa, 16);
1169         WRITEF(gmesa->buf, ModelViewProjectionMatrix0, m[0]);
1170         WRITEF(gmesa->buf, ModelViewProjectionMatrix1, m[1]);
1171         WRITEF(gmesa->buf, ModelViewProjectionMatrix2, m[2]);
1172         WRITEF(gmesa->buf, ModelViewProjectionMatrix3, m[3]);
1173         WRITEF(gmesa->buf, ModelViewProjectionMatrix4, m[4]);
1174         WRITEF(gmesa->buf, ModelViewProjectionMatrix5, m[5]);
1175         WRITEF(gmesa->buf, ModelViewProjectionMatrix6, m[6]);
1176         WRITEF(gmesa->buf, ModelViewProjectionMatrix7, m[7]);
1177         WRITEF(gmesa->buf, ModelViewProjectionMatrix8, m[8]);
1178         WRITEF(gmesa->buf, ModelViewProjectionMatrix9, m[9]);
1179         WRITEF(gmesa->buf, ModelViewProjectionMatrix10, m[10]);
1180         WRITEF(gmesa->buf, ModelViewProjectionMatrix11, m[11]);
1181         WRITEF(gmesa->buf, ModelViewProjectionMatrix12, m[12]);
1182         WRITEF(gmesa->buf, ModelViewProjectionMatrix13, m[13]);
1183         WRITEF(gmesa->buf, ModelViewProjectionMatrix14, m[14]);
1184         WRITEF(gmesa->buf, ModelViewProjectionMatrix15, m[15]);
1185         break;
1186     case GL_TEXTURE:
1187         m = ctx->TextureMatrixStack[0].Top->m;
1188         CHECK_DMA_BUFFER(gmesa, 16);
1189         gmesa->TransformMode |= XM_XformTexture;
1190         WRITEF(gmesa->buf, TextureMatrix0,  m[0]);
1191         WRITEF(gmesa->buf, TextureMatrix1,  m[1]);
1192         WRITEF(gmesa->buf, TextureMatrix2,  m[2]);
1193         WRITEF(gmesa->buf, TextureMatrix3,  m[3]);
1194         WRITEF(gmesa->buf, TextureMatrix4,  m[4]);
1195         WRITEF(gmesa->buf, TextureMatrix5,  m[5]);
1196         WRITEF(gmesa->buf, TextureMatrix6,  m[6]);
1197         WRITEF(gmesa->buf, TextureMatrix7,  m[7]);
1198         WRITEF(gmesa->buf, TextureMatrix8,  m[8]);
1199         WRITEF(gmesa->buf, TextureMatrix9,  m[9]);
1200         WRITEF(gmesa->buf, TextureMatrix10,  m[10]);
1201         WRITEF(gmesa->buf, TextureMatrix11,  m[11]);
1202         WRITEF(gmesa->buf, TextureMatrix12,  m[12]);
1203         WRITEF(gmesa->buf, TextureMatrix13,  m[13]);
1204         WRITEF(gmesa->buf, TextureMatrix14,  m[14]);
1205         WRITEF(gmesa->buf, TextureMatrix15,  m[15]);
1206         break;
1207
1208     default:
1209         /* ERROR!!! -- how did this happen? */
1210         break;
1211     }
1212
1213     gmesa->dirty |= GAMMA_UPLOAD_TRANSFORM;
1214 }
1215 #endif
1216
1217 /* =============================================================
1218  * State enable/disable
1219  */
1220
1221 static void gammaDDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
1222 {
1223    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
1224
1225    switch ( cap ) {
1226    case GL_ALPHA_TEST:
1227    case GL_BLEND:
1228       FLUSH_BATCH( gmesa );
1229       gmesa->new_state |= GAMMA_NEW_ALPHA;
1230       break;
1231
1232    case GL_CULL_FACE:
1233       FLUSH_BATCH( gmesa );
1234       gmesa->new_state |= GAMMA_NEW_CULL;
1235       break;
1236
1237    case GL_DEPTH_TEST:
1238       FLUSH_BATCH( gmesa );
1239       gmesa->new_state |= GAMMA_NEW_DEPTH;
1240       break;
1241
1242    case GL_DITHER:
1243       do {
1244          u_int32_t d = gmesa->DitherMode;
1245          FLUSH_BATCH( gmesa );
1246
1247          if ( state ) {
1248             d |=  DM_DitherEnable;
1249          } else {
1250             d &= ~DM_DitherEnable;
1251          }
1252
1253          if ( gmesa->DitherMode != d ) {
1254             gmesa->DitherMode = d;
1255             gmesa->dirty |= GAMMA_UPLOAD_DITHER;
1256          }
1257       } while (0);
1258       break;
1259
1260 #if 0
1261    case GL_FOG:
1262       FLUSH_BATCH( gmesa );
1263       gmesa->new_state |= GAMMA_NEW_FOG;
1264       break;
1265 #endif
1266
1267    case GL_INDEX_LOGIC_OP:
1268    case GL_COLOR_LOGIC_OP:
1269       FLUSH_BATCH( gmesa );
1270       gmesa->new_state |= GAMMA_NEW_LOGICOP;
1271       break;
1272
1273 #if ENABLELIGHTING
1274    case GL_LIGHTING:
1275       do {
1276          u_int32_t l = gmesa->LightingMode;
1277          FLUSH_BATCH( gmesa );
1278
1279          if ( state ) {
1280             l |=  LightingModeEnable;
1281          } else {
1282             l &= ~LightingModeEnable;
1283          }
1284
1285          if ( gmesa->LightingMode != l ) {
1286             gmesa->LightingMode = l;
1287             gmesa->dirty |= GAMMA_UPLOAD_LIGHT;
1288          }
1289       } while (0);
1290       break;
1291
1292    case GL_COLOR_MATERIAL:
1293       do {
1294          u_int32_t m = gmesa->MaterialMode;
1295          FLUSH_BATCH( gmesa );
1296
1297          if ( state ) {
1298             m |=  MaterialModeEnable;
1299          } else {
1300             m &= ~MaterialModeEnable;
1301          }
1302
1303          if ( gmesa->MaterialMode != m ) {
1304             gmesa->MaterialMode = m;
1305             gmesa->dirty |= GAMMA_UPLOAD_LIGHT;
1306          }
1307       } while (0);
1308       break;
1309 #endif
1310
1311    case GL_LINE_SMOOTH:
1312       FLUSH_BATCH( gmesa );
1313       if ( state ) {
1314          gmesa->AntialiasMode |= AntialiasModeEnable;
1315          gmesa->LineMode |= LM_AntialiasEnable;
1316       } else {
1317          gmesa->AntialiasMode &= ~AntialiasModeEnable;
1318          gmesa->LineMode &= ~LM_AntialiasEnable;
1319       }
1320       gmesa->dirty |= GAMMA_UPLOAD_LINEMODE;
1321       break;
1322
1323    case GL_POINT_SMOOTH:
1324       FLUSH_BATCH( gmesa );
1325       if ( state ) {
1326          gmesa->AntialiasMode |= AntialiasModeEnable;
1327          gmesa->PointMode |= PM_AntialiasEnable;
1328       } else {
1329          gmesa->AntialiasMode &= ~AntialiasModeEnable;
1330          gmesa->PointMode &= ~PM_AntialiasEnable;
1331       }
1332       gmesa->dirty |= GAMMA_UPLOAD_POINTMODE;
1333       break;
1334
1335    case GL_POLYGON_SMOOTH:
1336       FLUSH_BATCH( gmesa );
1337       if ( state ) {
1338          gmesa->AntialiasMode |= AntialiasModeEnable;
1339          gmesa->TriangleMode |= TM_AntialiasEnable;
1340       } else {
1341          gmesa->AntialiasMode &= ~AntialiasModeEnable;
1342          gmesa->TriangleMode &= ~TM_AntialiasEnable;
1343       }
1344       gmesa->dirty |= GAMMA_UPLOAD_TRIMODE;
1345       break;
1346
1347    case GL_SCISSOR_TEST:
1348       FLUSH_BATCH( gmesa );
1349       gmesa->new_state |= GAMMA_NEW_CLIP;
1350       break;
1351
1352    case GL_POLYGON_OFFSET_FILL:
1353    case GL_POLYGON_OFFSET_POINT:
1354    case GL_POLYGON_OFFSET_LINE:
1355       FLUSH_BATCH( gmesa );
1356       gmesa->new_state |= GAMMA_NEW_POLYGON;
1357       break;
1358
1359    case GL_LINE_STIPPLE:
1360       FLUSH_BATCH( gmesa );
1361       if ( state )
1362          gmesa->LineMode |= LM_StippleEnable;
1363       else
1364          gmesa->LineMode &= ~LM_StippleEnable;
1365       gmesa->dirty |= GAMMA_UPLOAD_LINEMODE;
1366       break;
1367
1368    case GL_POLYGON_STIPPLE:
1369       FLUSH_BATCH( gmesa );
1370       gmesa->new_state |= GAMMA_NEW_STIPPLE;
1371       break;
1372
1373    default:
1374       return;
1375    }
1376 }
1377
1378 /* =============================================================
1379  * State initialization, management
1380  */
1381
1382
1383 /*
1384  * Load the current context's state into the hardware.
1385  *
1386  * NOTE: Be VERY careful about ensuring the context state is marked for
1387  * upload, the only place it shouldn't be uploaded is when the setup
1388  * state has changed in ReducedPrimitiveChange as this comes right after
1389  * a state update.
1390  *
1391  * Blits of any type should always upload the context and masks after
1392  * they are done.
1393  */
1394 void gammaEmitHwState( gammaContextPtr gmesa )
1395 {
1396     if (!gmesa->driDrawable) return;
1397
1398     if (!gmesa->dirty) return;
1399
1400 #ifdef DO_VALIDATE
1401     /* Flush any partially filled buffers */
1402     FLUSH_DMA_BUFFER(gmesa);
1403
1404     DRM_SPINLOCK(&gmesa->driScreen->pSAREA->drawable_lock,
1405                  gmesa->driScreen->drawLockID);
1406     VALIDATE_DRAWABLE_INFO_NO_LOCK(gmesa);
1407 #endif
1408
1409     if (gmesa->dirty & GAMMA_UPLOAD_VIEWPORT) {
1410         gmesa->dirty &= ~GAMMA_UPLOAD_VIEWPORT;
1411         CHECK_DMA_BUFFER(gmesa, 6);
1412         WRITEF(gmesa->buf, ViewPortOffsetX, gmesa->ViewportOffsetX);
1413         WRITEF(gmesa->buf, ViewPortOffsetY, gmesa->ViewportOffsetY);
1414         WRITEF(gmesa->buf, ViewPortOffsetZ, gmesa->ViewportOffsetZ);
1415         WRITEF(gmesa->buf, ViewPortScaleX, gmesa->ViewportScaleX);
1416         WRITEF(gmesa->buf, ViewPortScaleY, gmesa->ViewportScaleY);
1417         WRITEF(gmesa->buf, ViewPortScaleZ, gmesa->ViewportScaleZ);
1418     }
1419     if ( (gmesa->dirty & GAMMA_UPLOAD_POINTMODE) ||
1420          (gmesa->dirty & GAMMA_UPLOAD_LINEMODE) ||
1421          (gmesa->dirty & GAMMA_UPLOAD_TRIMODE) ) {
1422         CHECK_DMA_BUFFER(gmesa, 1);
1423         WRITE(gmesa->buf, AntialiasMode, gmesa->AntialiasMode);
1424     }
1425     if (gmesa->dirty & GAMMA_UPLOAD_POINTMODE) {
1426         gmesa->dirty &= ~GAMMA_UPLOAD_POINTMODE;
1427         CHECK_DMA_BUFFER(gmesa, 1);
1428         WRITE(gmesa->buf, PointMode, gmesa->PointMode);
1429     }
1430     if (gmesa->dirty & GAMMA_UPLOAD_LINEMODE) {
1431         gmesa->dirty &= ~GAMMA_UPLOAD_LINEMODE;
1432         CHECK_DMA_BUFFER(gmesa, 2);
1433         WRITE(gmesa->buf, LineMode, gmesa->LineMode);
1434         WRITE(gmesa->buf, LineStippleMode, gmesa->LineMode);
1435     }
1436     if (gmesa->dirty & GAMMA_UPLOAD_TRIMODE) {
1437         gmesa->dirty &= ~GAMMA_UPLOAD_TRIMODE;
1438         CHECK_DMA_BUFFER(gmesa, 1);
1439         WRITE(gmesa->buf, TriangleMode, gmesa->TriangleMode);
1440     }
1441     if (gmesa->dirty & GAMMA_UPLOAD_FOG) {
1442         GLchan c[3], col;
1443         UNCLAMPED_FLOAT_TO_RGB_CHAN( c, gmesa->glCtx->Fog.Color );
1444         col = gammaPackColor(4, c[0], c[1], c[2], 0);
1445         gmesa->dirty &= ~GAMMA_UPLOAD_FOG;
1446         CHECK_DMA_BUFFER(gmesa, 5);
1447 #if 0
1448         WRITE(gmesa->buf, FogMode, gmesa->FogMode);
1449         WRITE(gmesa->buf, FogColor, col);
1450         WRITEF(gmesa->buf, FStart, gmesa->glCtx->Fog.Start);
1451 #endif
1452         WRITEF(gmesa->buf, FogEnd, gmesa->glCtx->Fog.End);
1453         WRITEF(gmesa->buf, FogDensity, gmesa->glCtx->Fog.Density);
1454         WRITEF(gmesa->buf, FogScale, 
1455                 1.0f/(gmesa->glCtx->Fog.End - gmesa->glCtx->Fog.Start));
1456     }
1457     if (gmesa->dirty & GAMMA_UPLOAD_DITHER) {
1458         gmesa->dirty &= ~GAMMA_UPLOAD_DITHER;
1459         CHECK_DMA_BUFFER(gmesa, 1);
1460         WRITE(gmesa->buf, DitherMode, gmesa->DitherMode);
1461     }
1462     if (gmesa->dirty & GAMMA_UPLOAD_LOGICOP) {
1463         gmesa->dirty &= ~GAMMA_UPLOAD_LOGICOP;
1464         CHECK_DMA_BUFFER(gmesa, 1);
1465         WRITE(gmesa->buf, LogicalOpMode, gmesa->LogicalOpMode);
1466     }
1467     if (gmesa->dirty & GAMMA_UPLOAD_CLIP) {
1468         gmesa->dirty &= ~GAMMA_UPLOAD_CLIP;
1469         CHECK_DMA_BUFFER(gmesa, 3);
1470         WRITE(gmesa->buf, ScissorMinXY, gmesa->ScissorMinXY);
1471         WRITE(gmesa->buf, ScissorMaxXY, gmesa->ScissorMaxXY);
1472         WRITE(gmesa->buf, ScissorMode, gmesa->ScissorMode);
1473     }
1474     if (gmesa->dirty & GAMMA_UPLOAD_MASKS) {
1475         gmesa->dirty &= ~GAMMA_UPLOAD_MASKS;
1476         CHECK_DMA_BUFFER(gmesa, 1);
1477         WRITE(gmesa->buf, FBHardwareWriteMask, gmesa->FBHardwareWriteMask);
1478     }
1479     if (gmesa->dirty & GAMMA_UPLOAD_ALPHA) {
1480         gmesa->dirty &= ~GAMMA_UPLOAD_ALPHA;
1481         CHECK_DMA_BUFFER(gmesa, 1);
1482         WRITE(gmesa->buf, AlphaTestMode, gmesa->AlphaTestMode);
1483     }
1484     if (gmesa->dirty & GAMMA_UPLOAD_BLEND) {
1485         gmesa->dirty &= ~GAMMA_UPLOAD_BLEND;
1486         CHECK_DMA_BUFFER(gmesa, 1);
1487         WRITE(gmesa->buf, AlphaBlendMode, gmesa->AlphaBlendMode);
1488     } 
1489     CHECK_DMA_BUFFER(gmesa, 1);
1490     if (gmesa->glCtx->Color.BlendEnabled || gmesa->glCtx->Color.AlphaEnabled) {
1491         WRITE(gmesa->buf, FBReadMode, gmesa->FBReadMode | gmesa->AB_FBReadMode_Save);
1492     } else {
1493         WRITE(gmesa->buf, FBReadMode, gmesa->FBReadMode);
1494     }
1495     if (gmesa->dirty & GAMMA_UPLOAD_LIGHT) {
1496         gmesa->dirty &= ~GAMMA_UPLOAD_LIGHT;
1497         CHECK_DMA_BUFFER(gmesa, 2);
1498         WRITE(gmesa->buf, LightingMode, gmesa->LightingMode);
1499         WRITE(gmesa->buf, MaterialMode, gmesa->MaterialMode);
1500     }
1501     if (gmesa->dirty & GAMMA_UPLOAD_SHADE) {
1502         gmesa->dirty &= ~GAMMA_UPLOAD_SHADE;
1503         CHECK_DMA_BUFFER(gmesa, 1);
1504         WRITE(gmesa->buf, ColorDDAMode, gmesa->ColorDDAMode);
1505     }
1506     if (gmesa->dirty & GAMMA_UPLOAD_POLYGON) {
1507         gmesa->dirty &= ~GAMMA_UPLOAD_POLYGON;
1508         CHECK_DMA_BUFFER(gmesa, 2);
1509         WRITEF(gmesa->buf, PolygonOffsetBias, gmesa->glCtx->Polygon.OffsetUnits);
1510         WRITEF(gmesa->buf, PolygonOffsetFactor, gmesa->glCtx->Polygon.OffsetFactor);
1511     }
1512     if (gmesa->dirty & GAMMA_UPLOAD_STIPPLE) {
1513         gmesa->dirty &= ~GAMMA_UPLOAD_STIPPLE;
1514         CHECK_DMA_BUFFER(gmesa, 33);
1515         WRITE(gmesa->buf, AreaStippleMode, gmesa->AreaStippleMode);
1516         WRITE(gmesa->buf, AreaStipplePattern0, gmesa->glCtx->PolygonStipple[0]);
1517         WRITE(gmesa->buf, AreaStipplePattern1, gmesa->glCtx->PolygonStipple[1]);
1518         WRITE(gmesa->buf, AreaStipplePattern2, gmesa->glCtx->PolygonStipple[2]);
1519         WRITE(gmesa->buf, AreaStipplePattern3, gmesa->glCtx->PolygonStipple[3]);
1520         WRITE(gmesa->buf, AreaStipplePattern4, gmesa->glCtx->PolygonStipple[4]);
1521         WRITE(gmesa->buf, AreaStipplePattern5, gmesa->glCtx->PolygonStipple[5]);
1522         WRITE(gmesa->buf, AreaStipplePattern6, gmesa->glCtx->PolygonStipple[6]);
1523         WRITE(gmesa->buf, AreaStipplePattern7, gmesa->glCtx->PolygonStipple[7]);
1524         WRITE(gmesa->buf, AreaStipplePattern8, gmesa->glCtx->PolygonStipple[8]);
1525         WRITE(gmesa->buf, AreaStipplePattern9, gmesa->glCtx->PolygonStipple[9]);
1526         WRITE(gmesa->buf, AreaStipplePattern10, gmesa->glCtx->PolygonStipple[10]);
1527         WRITE(gmesa->buf, AreaStipplePattern11, gmesa->glCtx->PolygonStipple[11]);
1528         WRITE(gmesa->buf, AreaStipplePattern12, gmesa->glCtx->PolygonStipple[12]);
1529         WRITE(gmesa->buf, AreaStipplePattern13, gmesa->glCtx->PolygonStipple[13]);
1530         WRITE(gmesa->buf, AreaStipplePattern14, gmesa->glCtx->PolygonStipple[14]);
1531         WRITE(gmesa->buf, AreaStipplePattern15, gmesa->glCtx->PolygonStipple[15]);
1532         WRITE(gmesa->buf, AreaStipplePattern16, gmesa->glCtx->PolygonStipple[16]);
1533         WRITE(gmesa->buf, AreaStipplePattern17, gmesa->glCtx->PolygonStipple[17]);
1534         WRITE(gmesa->buf, AreaStipplePattern18, gmesa->glCtx->PolygonStipple[18]);
1535         WRITE(gmesa->buf, AreaStipplePattern19, gmesa->glCtx->PolygonStipple[19]);
1536         WRITE(gmesa->buf, AreaStipplePattern20, gmesa->glCtx->PolygonStipple[20]);
1537         WRITE(gmesa->buf, AreaStipplePattern21, gmesa->glCtx->PolygonStipple[21]);
1538         WRITE(gmesa->buf, AreaStipplePattern22, gmesa->glCtx->PolygonStipple[22]);
1539         WRITE(gmesa->buf, AreaStipplePattern23, gmesa->glCtx->PolygonStipple[23]);
1540         WRITE(gmesa->buf, AreaStipplePattern24, gmesa->glCtx->PolygonStipple[24]);
1541         WRITE(gmesa->buf, AreaStipplePattern25, gmesa->glCtx->PolygonStipple[25]);
1542         WRITE(gmesa->buf, AreaStipplePattern26, gmesa->glCtx->PolygonStipple[26]);
1543         WRITE(gmesa->buf, AreaStipplePattern27, gmesa->glCtx->PolygonStipple[27]);
1544         WRITE(gmesa->buf, AreaStipplePattern28, gmesa->glCtx->PolygonStipple[28]);
1545         WRITE(gmesa->buf, AreaStipplePattern29, gmesa->glCtx->PolygonStipple[29]);
1546         WRITE(gmesa->buf, AreaStipplePattern30, gmesa->glCtx->PolygonStipple[30]);
1547         WRITE(gmesa->buf, AreaStipplePattern31, gmesa->glCtx->PolygonStipple[31]);
1548     }
1549     if (gmesa->dirty & GAMMA_UPLOAD_DEPTH) {
1550         gmesa->dirty &= ~GAMMA_UPLOAD_DEPTH;
1551         CHECK_DMA_BUFFER(gmesa, 4);
1552         WRITE(gmesa->buf, DepthMode,  gmesa->DepthMode);
1553         WRITE(gmesa->buf, DeltaMode,  gmesa->DeltaMode);
1554         WRITE(gmesa->buf, GLINTWindow,gmesa->Window | (gmesa->FrameCount << 9));
1555         WRITE(gmesa->buf, LBReadMode, gmesa->LBReadMode);
1556     }
1557     if (gmesa->dirty & GAMMA_UPLOAD_GEOMETRY) {
1558         gmesa->dirty &= ~GAMMA_UPLOAD_GEOMETRY;
1559         CHECK_DMA_BUFFER(gmesa, 1);
1560         WRITE(gmesa->buf, GeometryMode, gmesa->GeometryMode);
1561     }
1562     if (gmesa->dirty & GAMMA_UPLOAD_TRANSFORM) {
1563         gmesa->dirty &= ~GAMMA_UPLOAD_TRANSFORM;
1564         CHECK_DMA_BUFFER(gmesa, 1);
1565         WRITE(gmesa->buf, TransformMode, gmesa->TransformMode);
1566     }
1567     if (gmesa->dirty & GAMMA_UPLOAD_TEX0) {
1568         gammaTextureObjectPtr curTex = gmesa->CurrentTexObj[0];
1569         gmesa->dirty &= ~GAMMA_UPLOAD_TEX0;
1570         if (curTex) {
1571         CHECK_DMA_BUFFER(gmesa, 21);
1572         WRITE(gmesa->buf, GeometryMode, gmesa->GeometryMode | GM_TextureEnable);
1573         WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode | DM_TextureEnable);
1574         WRITE(gmesa->buf, TextureAddressMode, curTex->TextureAddressMode);
1575         WRITE(gmesa->buf, TextureReadMode, curTex->TextureReadMode);
1576         WRITE(gmesa->buf, TextureColorMode, curTex->TextureColorMode);
1577         WRITE(gmesa->buf, TextureFilterMode, curTex->TextureFilterMode);
1578         WRITE(gmesa->buf, TextureFormat, curTex->TextureFormat);
1579         WRITE(gmesa->buf, GLINTBorderColor, curTex->TextureBorderColor);
1580         WRITE(gmesa->buf, TxBaseAddr0, curTex->TextureBaseAddr[0]);
1581         WRITE(gmesa->buf, TxBaseAddr1, curTex->TextureBaseAddr[1]);
1582         WRITE(gmesa->buf, TxBaseAddr2, curTex->TextureBaseAddr[2]);
1583         WRITE(gmesa->buf, TxBaseAddr3, curTex->TextureBaseAddr[3]);
1584         WRITE(gmesa->buf, TxBaseAddr4, curTex->TextureBaseAddr[4]);
1585         WRITE(gmesa->buf, TxBaseAddr5, curTex->TextureBaseAddr[5]);
1586         WRITE(gmesa->buf, TxBaseAddr6, curTex->TextureBaseAddr[6]);
1587         WRITE(gmesa->buf, TxBaseAddr7, curTex->TextureBaseAddr[7]);
1588         WRITE(gmesa->buf, TxBaseAddr8, curTex->TextureBaseAddr[8]);
1589         WRITE(gmesa->buf, TxBaseAddr9, curTex->TextureBaseAddr[9]);
1590         WRITE(gmesa->buf, TxBaseAddr10, curTex->TextureBaseAddr[10]);
1591         WRITE(gmesa->buf, TxBaseAddr11, curTex->TextureBaseAddr[11]);
1592         WRITE(gmesa->buf, TextureCacheControl, (TCC_Enable | TCC_Invalidate));
1593         } else {
1594         CHECK_DMA_BUFFER(gmesa, 6);
1595         WRITE(gmesa->buf, GeometryMode, gmesa->GeometryMode);
1596         WRITE(gmesa->buf, DeltaMode, gmesa->DeltaMode);
1597         WRITE(gmesa->buf, TextureAddressMode, TextureAddressModeDisable);
1598         WRITE(gmesa->buf, TextureReadMode, TextureReadModeDisable);
1599         WRITE(gmesa->buf, TextureFilterMode, TextureFilterModeDisable);
1600         WRITE(gmesa->buf, TextureColorMode, TextureColorModeDisable);
1601         }
1602     }
1603 #ifdef DO_VALIDATE
1604     PROCESS_DMA_BUFFER_TOP_HALF(gmesa);
1605
1606     DRM_SPINUNLOCK(&gmesa->driScreen->pSAREA->drawable_lock,
1607                    gmesa->driScreen->drawLockID);
1608     VALIDATE_DRAWABLE_INFO_NO_LOCK_POST(gmesa);
1609
1610     PROCESS_DMA_BUFFER_BOTTOM_HALF(gmesa);
1611 #endif
1612 }
1613
1614 void gammaDDUpdateHWState( GLcontext *ctx )
1615 {
1616    gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
1617    int new_state = gmesa->new_state;
1618
1619    if ( new_state )
1620    {
1621       FLUSH_BATCH( gmesa );
1622
1623       gmesa->new_state = 0;
1624
1625       /* Update the various parts of the context's state.
1626        */
1627       if ( new_state & GAMMA_NEW_ALPHA )
1628          gammaUpdateAlphaMode( ctx );
1629
1630       if ( new_state & GAMMA_NEW_DEPTH )
1631          gammaUpdateZMode( ctx );
1632
1633       if ( new_state & GAMMA_NEW_FOG )
1634          gammaUpdateFogAttrib( ctx );
1635
1636       if ( new_state & GAMMA_NEW_CLIP )
1637          gammaUpdateClipping( ctx );
1638
1639       if ( new_state & GAMMA_NEW_POLYGON )
1640          gammaUpdatePolygon( ctx );
1641
1642       if ( new_state & GAMMA_NEW_CULL )
1643          gammaUpdateCull( ctx );
1644
1645       if ( new_state & GAMMA_NEW_MASKS )
1646          gammaUpdateMasks( ctx );
1647
1648       if ( new_state & GAMMA_NEW_WINDOW )
1649          gammaUpdateWindow( ctx );
1650
1651       if ( new_state & GAMMA_NEW_STIPPLE )
1652          gammaUpdateStipple( ctx );
1653    }
1654
1655    /* HACK ! */
1656
1657    gammaEmitHwState( gmesa );
1658 }
1659
1660
1661 static void gammaDDUpdateState( GLcontext *ctx, GLuint new_state )
1662 {
1663    _swrast_InvalidateState( ctx, new_state );
1664    _swsetup_InvalidateState( ctx, new_state );
1665    _vbo_InvalidateState( ctx, new_state );
1666    _tnl_InvalidateState( ctx, new_state );
1667    GAMMA_CONTEXT(ctx)->new_gl_state |= new_state;
1668 }
1669
1670
1671 /* Initialize the context's hardware state.
1672  */
1673 void gammaDDInitState( gammaContextPtr gmesa )
1674 {
1675    gmesa->new_state = 0;
1676 }
1677
1678 /* Initialize the driver's state functions.
1679  */
1680 void gammaDDInitStateFuncs( GLcontext *ctx )
1681 {
1682    ctx->Driver.UpdateState              = gammaDDUpdateState;
1683
1684    ctx->Driver.Clear                    = gammaDDClear;
1685    ctx->Driver.ClearIndex               = NULL;
1686    ctx->Driver.ClearColor               = gammaDDClearColor;
1687    ctx->Driver.DrawBuffer               = gammaDDDrawBuffer;
1688    ctx->Driver.ReadBuffer               = gammaDDReadBuffer;
1689
1690    ctx->Driver.IndexMask                = NULL;
1691    ctx->Driver.ColorMask                = gammaDDColorMask;
1692
1693    ctx->Driver.AlphaFunc                = gammaDDAlphaFunc;
1694    ctx->Driver.BlendEquationSeparate    = gammaDDBlendEquationSeparate;
1695    ctx->Driver.BlendFuncSeparate        = gammaDDBlendFuncSeparate;
1696    ctx->Driver.ClearDepth               = gammaDDClearDepth;
1697    ctx->Driver.CullFace                 = gammaDDCullFace;
1698    ctx->Driver.FrontFace                = gammaDDFrontFace;
1699    ctx->Driver.DepthFunc                = gammaDDDepthFunc;
1700    ctx->Driver.DepthMask                = gammaDDDepthMask;
1701    ctx->Driver.DepthRange               = gammaDDDepthRange;
1702    ctx->Driver.Enable                   = gammaDDEnable;
1703    ctx->Driver.Finish                   = gammaDDFinish;
1704    ctx->Driver.Flush                    = gammaDDFlush;
1705 #if 0
1706    ctx->Driver.Fogfv                    = gammaDDFogfv;
1707 #endif
1708    ctx->Driver.Hint                     = NULL;
1709    ctx->Driver.LineWidth                = gammaDDLineWidth;
1710    ctx->Driver.LineStipple              = gammaDDLineStipple;
1711 #if ENABLELIGHTING
1712    ctx->Driver.Lightfv                  = gammaDDLightfv; 
1713    ctx->Driver.LightModelfv             = gammaDDLightModelfv;
1714 #endif
1715    ctx->Driver.LogicOpcode              = gammaDDLogicalOpcode;
1716    ctx->Driver.PointSize                = gammaDDPointSize;
1717    ctx->Driver.PolygonMode              = gammaDDPolygonMode;
1718    ctx->Driver.PolygonStipple           = gammaDDPolygonStipple;
1719    ctx->Driver.Scissor                  = gammaDDScissor;
1720    ctx->Driver.ShadeModel               = gammaDDShadeModel;
1721    ctx->Driver.Viewport                 = gammaDDViewport;
1722 }