Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / mach64 / mach64_state.c
1 /* -*- mode: c; c-basic-offset: 3 -*- */
2 /*
3  * Copyright 2000 Gareth Hughes
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 /*
26  * Authors:
27  *      Gareth Hughes <gareth@valinux.com>
28  *      Leif Delgass <ldelgass@retinalburn.net>
29  *      Jos�Fonseca <j_r_fonseca@yahoo.co.uk>
30  */
31
32 #include "mach64_context.h"
33 #include "mach64_state.h"
34 #include "mach64_ioctl.h"
35 #include "mach64_tris.h"
36 #include "mach64_vb.h"
37 #include "mach64_tex.h"
38
39 #include "main/enums.h"
40 #include "main/colormac.h"
41 #include "swrast/swrast.h"
42 #include "vbo/vbo.h"
43 #include "tnl/tnl.h"
44 #include "swrast_setup/swrast_setup.h"
45
46
47 /* =============================================================
48  * Alpha blending
49  */
50
51 static void mach64UpdateAlphaMode( struct gl_context *ctx )
52 {
53    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
54    GLuint a = mmesa->setup.alpha_tst_cntl;
55    GLuint s = mmesa->setup.scale_3d_cntl;
56    GLuint m = mmesa->setup.dp_write_mask;
57
58    if ( ctx->Color.AlphaEnabled ) {
59       GLubyte ref;
60
61       CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
62
63       a &= ~(MACH64_ALPHA_TEST_MASK | MACH64_REF_ALPHA_MASK);
64
65       switch ( ctx->Color.AlphaFunc ) {
66       case GL_NEVER:
67          a |= MACH64_ALPHA_TEST_NEVER;
68          break;
69       case GL_LESS:
70          a |= MACH64_ALPHA_TEST_LESS;
71          break;
72       case GL_LEQUAL:
73          a |= MACH64_ALPHA_TEST_LEQUAL;
74          break;
75       case GL_EQUAL:
76          a |= MACH64_ALPHA_TEST_EQUAL;
77          break;
78       case GL_GEQUAL:
79          a |= MACH64_ALPHA_TEST_GEQUAL;
80          break;
81       case GL_GREATER:
82          a |= MACH64_ALPHA_TEST_GREATER;
83          break;
84       case GL_NOTEQUAL:
85          a |= MACH64_ALPHA_TEST_NOTEQUAL;
86          break;
87       case GL_ALWAYS:
88          a |= MACH64_ALPHA_TEST_ALWAYS;
89          break;
90       }
91
92       a |= (ref << MACH64_REF_ALPHA_SHIFT);
93       a |=  MACH64_ALPHA_TEST_EN;
94    } else {
95       a &= ~MACH64_ALPHA_TEST_EN;
96    }
97
98    FALLBACK( mmesa, MACH64_FALLBACK_BLEND_FUNC, GL_FALSE );
99
100    if ( ctx->Color.BlendEnabled ) {
101       s &= ~(MACH64_ALPHA_BLEND_SRC_MASK |
102              MACH64_ALPHA_BLEND_DST_MASK |
103              MACH64_ALPHA_BLEND_SAT);
104
105       switch ( ctx->Color.Blend[0].SrcRGB ) {
106       case GL_ZERO:
107          s |= MACH64_ALPHA_BLEND_SRC_ZERO;
108          break;
109       case GL_ONE:
110          s |= MACH64_ALPHA_BLEND_SRC_ONE;
111          break;
112       case GL_DST_COLOR:
113          s |= MACH64_ALPHA_BLEND_SRC_DSTCOLOR;
114          break;
115       case GL_ONE_MINUS_DST_COLOR:
116          s |= MACH64_ALPHA_BLEND_SRC_INVDSTCOLOR;
117          break;
118       case GL_SRC_ALPHA:
119          s |= MACH64_ALPHA_BLEND_SRC_SRCALPHA;
120          break;
121       case GL_ONE_MINUS_SRC_ALPHA:
122          s |= MACH64_ALPHA_BLEND_SRC_INVSRCALPHA;
123          break;
124       case GL_DST_ALPHA:
125          s |= MACH64_ALPHA_BLEND_SRC_DSTALPHA;
126          break;
127       case GL_ONE_MINUS_DST_ALPHA:
128          s |= MACH64_ALPHA_BLEND_SRC_INVDSTALPHA;
129          break;
130       case GL_SRC_ALPHA_SATURATE:
131          s |= (MACH64_ALPHA_BLEND_SRC_SRCALPHA |
132                MACH64_ALPHA_BLEND_SAT);
133          break;
134       default:
135          FALLBACK( mmesa, MACH64_FALLBACK_BLEND_FUNC, GL_TRUE );
136       }
137
138       switch ( ctx->Color.Blend[0].DstRGB ) {
139       case GL_ZERO:
140          s |= MACH64_ALPHA_BLEND_DST_ZERO;
141          break;
142       case GL_ONE:
143          s |= MACH64_ALPHA_BLEND_DST_ONE;
144          break;
145       case GL_SRC_COLOR:
146          s |= MACH64_ALPHA_BLEND_DST_SRCCOLOR;
147          break;
148       case GL_ONE_MINUS_SRC_COLOR:
149          s |= MACH64_ALPHA_BLEND_DST_INVSRCCOLOR;
150          break;
151       case GL_SRC_ALPHA:
152          s |= MACH64_ALPHA_BLEND_DST_SRCALPHA;
153          break;
154       case GL_ONE_MINUS_SRC_ALPHA:
155          s |= MACH64_ALPHA_BLEND_DST_INVSRCALPHA;
156          break;
157       case GL_DST_ALPHA:
158          s |= MACH64_ALPHA_BLEND_DST_DSTALPHA;
159          break;
160       case GL_ONE_MINUS_DST_ALPHA:
161          s |= MACH64_ALPHA_BLEND_DST_INVDSTALPHA;
162          break;
163       default:
164          FALLBACK( mmesa, MACH64_FALLBACK_BLEND_FUNC, GL_TRUE );
165       }
166
167       m = 0xffffffff; /* Can't color mask and blend at the same time */
168       s &= ~MACH64_ALPHA_FOG_EN_FOG; /* Can't fog and blend at the same time */
169       s |=  MACH64_ALPHA_FOG_EN_ALPHA;
170    } else {
171       s &= ~MACH64_ALPHA_FOG_EN_ALPHA;
172    }
173
174    if ( mmesa->setup.alpha_tst_cntl != a ) {
175       mmesa->setup.alpha_tst_cntl = a;
176       mmesa->dirty |= MACH64_UPLOAD_Z_ALPHA_CNTL;
177    }
178    if ( mmesa->setup.scale_3d_cntl != s ) {
179       mmesa->setup.scale_3d_cntl = s;
180       mmesa->dirty |= MACH64_UPLOAD_SCALE_3D_CNTL;
181    }
182    if ( mmesa->setup.dp_write_mask != m ) {
183       mmesa->setup.dp_write_mask = m;
184       mmesa->dirty |= MACH64_UPLOAD_DP_WRITE_MASK;
185    }
186 }
187
188 static void mach64DDAlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
189 {
190    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
191
192    FLUSH_BATCH( mmesa );
193    mmesa->new_state |= MACH64_NEW_ALPHA;
194 }
195
196 static void mach64DDBlendEquationSeparate( struct gl_context *ctx, 
197                                            GLenum modeRGB, GLenum modeA )
198 {
199    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
200
201    assert( modeRGB == modeA );
202    FLUSH_BATCH( mmesa );
203
204    /* BlendEquation affects ColorLogicOpEnabled
205     */
206    FALLBACK( MACH64_CONTEXT(ctx), MACH64_FALLBACK_LOGICOP,
207              (ctx->Color.ColorLogicOpEnabled &&
208               ctx->Color.LogicOp != GL_COPY));
209
210    /* Can only do blend addition, not min, max, subtract, etc. */
211    FALLBACK( MACH64_CONTEXT(ctx), MACH64_FALLBACK_BLEND_EQ,
212              modeRGB != GL_FUNC_ADD);
213
214    mmesa->new_state |= MACH64_NEW_ALPHA;
215 }
216
217 static void mach64DDBlendFuncSeparate( struct gl_context *ctx,
218                                        GLenum sfactorRGB, GLenum dfactorRGB,
219                                        GLenum sfactorA, GLenum dfactorA )
220 {
221    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
222
223    FLUSH_BATCH( mmesa );
224    mmesa->new_state |= MACH64_NEW_ALPHA;
225 }
226
227
228 /* =============================================================
229  * Depth testing
230  */
231
232 static void mach64UpdateZMode( struct gl_context *ctx )
233 {
234    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
235    GLuint z = mmesa->setup.z_cntl;
236
237    if ( MACH64_DEBUG & DEBUG_VERBOSE_MSG ) {
238       fprintf( stderr, "%s:\n", __FUNCTION__ );
239    }
240
241    if ( ctx->Depth.Test ) {
242       z &= ~MACH64_Z_TEST_MASK;
243
244       switch ( ctx->Depth.Func ) {
245       case GL_NEVER:
246          z |= MACH64_Z_TEST_NEVER;
247          break;
248       case GL_ALWAYS:
249          z |= MACH64_Z_TEST_ALWAYS;
250          break;
251       case GL_LESS:
252          z |= MACH64_Z_TEST_LESS;
253          break;
254       case GL_LEQUAL:
255          z |= MACH64_Z_TEST_LEQUAL;
256          break;
257       case GL_EQUAL:
258          z |= MACH64_Z_TEST_EQUAL;
259          break;
260       case GL_GEQUAL:
261          z |= MACH64_Z_TEST_GEQUAL;
262          break;
263       case GL_GREATER:
264          z |= MACH64_Z_TEST_GREATER;
265          break;
266       case GL_NOTEQUAL:
267          z |= MACH64_Z_TEST_NOTEQUAL;
268          break;
269       }
270
271       z |=  MACH64_Z_EN;
272    } else {
273       z &= ~MACH64_Z_EN;
274    }
275
276    if ( ctx->Depth.Mask ) {
277       z |=  MACH64_Z_MASK_EN;
278    } else {
279       z &= ~MACH64_Z_MASK_EN;
280    }
281
282    if ( mmesa->setup.z_cntl != z ) {
283       mmesa->setup.z_cntl = z;
284       mmesa->dirty |= MACH64_UPLOAD_Z_ALPHA_CNTL;
285    }
286 }
287
288 static void mach64DDDepthFunc( struct gl_context *ctx, GLenum func )
289 {
290    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
291
292    FLUSH_BATCH( mmesa );
293    mmesa->new_state |= MACH64_NEW_DEPTH;
294 }
295
296 static void mach64DDDepthMask( struct gl_context *ctx, GLboolean flag )
297 {
298    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
299
300    FLUSH_BATCH( mmesa );
301    mmesa->new_state |= MACH64_NEW_DEPTH;
302 }
303
304 static void mach64DDClearDepth( struct gl_context *ctx, GLclampd d )
305 {
306    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
307
308    /* Always have a 16-bit depth buffer.
309     */
310    mmesa->ClearDepth = d * 0xffff;
311 }
312
313
314 /* =============================================================
315  * Fog
316  */
317
318 static void mach64UpdateFogAttrib( struct gl_context *ctx )
319 {
320    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
321
322    CARD32 s = mmesa->setup.scale_3d_cntl;
323    GLubyte c[4];
324    CARD32 col;
325
326    /* Can't fog if blending is on */
327    if ( ctx->Color.BlendEnabled )
328       return;
329
330    if ( ctx->Fog.Enabled ) {
331       s |= MACH64_ALPHA_FOG_EN_FOG;
332       s &= ~(MACH64_ALPHA_BLEND_SRC_MASK |
333              MACH64_ALPHA_BLEND_DST_MASK |
334              MACH64_ALPHA_BLEND_SAT);
335       /* From Utah-glx: "fog color is now dest and fog factor is alpha, so
336        * use GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA"
337        */
338       s |= (MACH64_ALPHA_BLEND_SRC_SRCALPHA | 
339             MACH64_ALPHA_BLEND_DST_INVSRCALPHA);
340       /* From Utah-glx: "can't use texture alpha when fogging" */
341       s &= ~MACH64_TEX_MAP_AEN;
342    } else {
343       s &= ~(MACH64_ALPHA_BLEND_SRC_MASK |
344              MACH64_ALPHA_BLEND_DST_MASK |
345              MACH64_ALPHA_BLEND_SAT);
346       s |= (MACH64_ALPHA_BLEND_SRC_ONE | 
347             MACH64_ALPHA_BLEND_DST_ZERO);
348       s &= ~MACH64_ALPHA_FOG_EN_FOG;
349    }
350
351    c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] );
352    c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] );
353    c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] );
354    c[3] = FLOAT_TO_UBYTE( ctx->Fog.Color[3] );
355
356    col = mach64PackColor( 4, c[0], c[1], c[2], c[3] );
357
358    if ( mmesa->setup.dp_fog_clr != col ) {
359       mmesa->setup.dp_fog_clr = col;
360       mmesa->dirty |= MACH64_UPLOAD_DP_FOG_CLR;
361    }
362    if ( mmesa->setup.scale_3d_cntl != s ) {
363       mmesa->setup.scale_3d_cntl = s;
364       mmesa->dirty |= MACH64_UPLOAD_SCALE_3D_CNTL;
365    }
366
367 }
368
369 static void mach64DDFogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
370 {
371    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
372
373    FLUSH_BATCH( mmesa );
374    mmesa->new_state |= MACH64_NEW_FOG;
375 }
376
377
378 /* =============================================================
379  * Clipping
380  */
381
382 static void mach64UpdateClipping( struct gl_context *ctx )
383 {
384    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
385    mach64ScreenPtr mach64Screen = mmesa->mach64Screen;
386
387    if ( mmesa->driDrawable ) {
388       __DRIdrawable *drawable = mmesa->driDrawable;
389       int x1 = 0;
390       int y1 = 0;
391       int x2 = drawable->w - 1;
392       int y2 = drawable->h - 1;
393
394       if ( ctx->Scissor.Enabled ) {
395          if ( ctx->Scissor.X > x1 ) {
396             x1 = ctx->Scissor.X;
397          }
398          if ( drawable->h - ctx->Scissor.Y - ctx->Scissor.Height > y1 ) {
399             y1 = drawable->h - ctx->Scissor.Y - ctx->Scissor.Height;
400          }
401          if ( ctx->Scissor.X + ctx->Scissor.Width - 1 < x2 ) {
402             x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
403          }
404          if ( drawable->h - ctx->Scissor.Y - 1 < y2 ) {
405             y2 = drawable->h - ctx->Scissor.Y - 1;
406          }
407       }
408
409       x1 += drawable->x;
410       y1 += drawable->y;
411       x2 += drawable->x;
412       y2 += drawable->y;
413
414       /* clamp to screen borders */
415       if (x1 < 0) x1 = 0;
416       if (y1 < 0) y1 = 0;
417       if (x2 < 0) x2 = 0;
418       if (y2 < 0) y2 = 0;
419       if (x2 > mach64Screen->width-1) x2 = mach64Screen->width-1;
420       if (y2 > mach64Screen->height-1) y2 = mach64Screen->height-1;
421
422       if ( MACH64_DEBUG & DEBUG_VERBOSE_MSG ) {
423          fprintf( stderr, "%s: drawable %3d %3d %3d %3d\n",
424                   __FUNCTION__,
425                   drawable->x,
426                   drawable->y,
427                   drawable->w,
428                   drawable->h );
429          fprintf( stderr, "%s:  scissor %3d %3d %3d %3d\n",
430                   __FUNCTION__,
431                   ctx->Scissor.X,
432                   ctx->Scissor.Y,
433                   ctx->Scissor.Width,
434                   ctx->Scissor.Height );
435          fprintf( stderr, "%s:    final %3d %3d %3d %3d\n",
436                   __FUNCTION__, x1, y1, x2, y2 );
437          fprintf( stderr, "\n" );
438       }
439
440       mmesa->setup.sc_top_bottom = ((y1 << 0) |
441                                     (y2 << 16));
442
443       mmesa->setup.sc_left_right = ((x1 << 0) |
444                                     (x2 << 16));
445
446        /* UPLOAD_MISC reduces the dirty state, we just need to
447        * emit the scissor to the SAREA.  We need to dirty cliprects
448        * since the scissor and cliprects are intersected to update the
449        * single hardware scissor
450        */
451       mmesa->dirty |= MACH64_UPLOAD_MISC | MACH64_UPLOAD_CLIPRECTS;
452    }
453 }
454
455 static void mach64DDScissor( struct gl_context *ctx,
456                              GLint x, GLint y, GLsizei w, GLsizei h )
457 {
458    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
459
460    FLUSH_BATCH( mmesa );
461    mmesa->new_state |= MACH64_NEW_CLIP;
462 }
463
464
465 /* =============================================================
466  * Culling
467  */
468
469 static void mach64UpdateCull( struct gl_context *ctx )
470 {
471    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
472    GLfloat backface_sign = 1;
473
474    if ( ctx->Polygon.CullFlag /*&& ctx->PB->primitive == GL_POLYGON*/ ) {
475       backface_sign = 1;
476       switch ( ctx->Polygon.CullFaceMode ) {
477       case GL_BACK:
478          if ( ctx->Polygon.FrontFace == GL_CCW )
479             backface_sign = -1;
480          break;
481       case GL_FRONT:
482          if ( ctx->Polygon.FrontFace != GL_CCW )
483             backface_sign = -1;
484          break;
485       default:
486       case GL_FRONT_AND_BACK:
487          backface_sign = 0;
488          break;
489       }
490    } else {
491       backface_sign = 0;
492    }
493
494    mmesa->backface_sign = backface_sign;
495
496 }
497
498 static void mach64DDCullFace( struct gl_context *ctx, GLenum mode )
499 {
500    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
501
502    FLUSH_BATCH( mmesa );
503    mmesa->new_state |= MACH64_NEW_CULL;
504 }
505
506 static void mach64DDFrontFace( struct gl_context *ctx, GLenum mode )
507 {
508    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
509
510    FLUSH_BATCH( mmesa );
511    mmesa->new_state |= MACH64_NEW_CULL;
512 }
513
514
515 /* =============================================================
516  * Masks
517  */
518
519 static void mach64UpdateMasks( struct gl_context *ctx )
520 {
521    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
522    GLuint mask = 0xffffffff;
523
524    /* mach64 can't color mask with alpha blending enabled */
525    if ( !ctx->Color.BlendEnabled ) {
526       mask = mach64PackColor( mmesa->mach64Screen->cpp,
527                               ctx->Color.ColorMask[0][RCOMP],
528                               ctx->Color.ColorMask[0][GCOMP],
529                               ctx->Color.ColorMask[0][BCOMP],
530                               ctx->Color.ColorMask[0][ACOMP] );
531    }
532
533    if ( mmesa->setup.dp_write_mask != mask ) {
534       mmesa->setup.dp_write_mask = mask;
535       mmesa->dirty |= MACH64_UPLOAD_DP_WRITE_MASK;
536    }
537 }
538
539 static void mach64DDColorMask( struct gl_context *ctx,
540                                GLboolean r, GLboolean g,
541                                GLboolean b, GLboolean a )
542 {
543    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
544
545    FLUSH_BATCH( mmesa );
546    mmesa->new_state |= MACH64_NEW_MASKS;
547 }
548
549
550 /* =============================================================
551  * Rendering attributes
552  *
553  * We really don't want to recalculate all this every time we bind a
554  * texture.  These things shouldn't change all that often, so it makes
555  * sense to break them out of the core texture state update routines.
556  */
557
558 static void mach64UpdateSpecularLighting( struct gl_context *ctx )
559 {
560    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
561    GLuint a = mmesa->setup.alpha_tst_cntl;
562
563    if ( MACH64_DEBUG & DEBUG_VERBOSE_MSG ) {
564       fprintf( stderr, "%s:\n", __FUNCTION__ );
565    }
566
567    if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR  &&
568         ctx->Light.Enabled ) {
569       a |=  MACH64_SPECULAR_LIGHT_EN;
570    } else {
571       a &= ~MACH64_SPECULAR_LIGHT_EN;
572    }
573
574    if ( mmesa->setup.alpha_tst_cntl != a ) {
575       mmesa->setup.alpha_tst_cntl = a;
576       mmesa->dirty |= MACH64_UPLOAD_Z_ALPHA_CNTL;
577       mmesa->new_state |= MACH64_NEW_CONTEXT;
578    }
579 }
580
581 static void mach64DDLightModelfv( struct gl_context *ctx, GLenum pname,
582                                   const GLfloat *param )
583 {
584    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
585
586    if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) {
587       FLUSH_BATCH( mmesa );
588       mach64UpdateSpecularLighting(ctx);
589    }
590 }
591
592 static void mach64DDShadeModel( struct gl_context *ctx, GLenum mode )
593 {
594    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
595    GLuint s = mmesa->setup.setup_cntl;
596
597    s &= ~MACH64_FLAT_SHADE_MASK;
598
599    switch ( mode ) {
600    case GL_FLAT:
601       s |= MACH64_FLAT_SHADE_VERTEX_3;
602       break;
603    case GL_SMOOTH:
604       s |= MACH64_FLAT_SHADE_OFF;
605       break;
606    default:
607       return;
608    }
609
610    if ( mmesa->setup.setup_cntl != s ) {
611       FLUSH_BATCH( mmesa );
612       mmesa->setup.setup_cntl = s;
613
614       mmesa->dirty |= MACH64_UPLOAD_SETUP_CNTL;
615    }
616 }
617
618
619 /* =============================================================
620  * Viewport
621  */
622
623
624 void mach64CalcViewport( struct gl_context *ctx )
625 {
626    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
627    const GLfloat *v = ctx->Viewport._WindowMap.m;
628    GLfloat *m = mmesa->hw_viewport;
629
630    /* See also mach64_translate_vertex.
631     */
632    m[MAT_SX] =   v[MAT_SX];
633    m[MAT_TX] =   v[MAT_TX] + (GLfloat)mmesa->drawX + SUBPIXEL_X;
634    m[MAT_SY] = - v[MAT_SY];
635    m[MAT_TY] = - v[MAT_TY] + mmesa->driDrawable->h + (GLfloat)mmesa->drawY + SUBPIXEL_Y;
636    m[MAT_SZ] =   v[MAT_SZ] * mmesa->depth_scale;
637    m[MAT_TZ] =   v[MAT_TZ] * mmesa->depth_scale;
638
639    mmesa->SetupNewInputs = ~0;
640 }
641
642 static void mach64Viewport( struct gl_context *ctx,
643                           GLint x, GLint y,
644                           GLsizei width, GLsizei height )
645 {
646    mach64CalcViewport( ctx );
647 }
648
649 static void mach64DepthRange( struct gl_context *ctx,
650                             GLclampd nearval, GLclampd farval )
651 {
652    mach64CalcViewport( ctx );
653 }
654
655
656 /* =============================================================
657  * Miscellaneous
658  */
659
660 static void mach64DDClearColor( struct gl_context *ctx,
661                                 const GLfloat color[4] )
662 {
663    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
664    GLubyte c[4];
665    
666    CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
667    CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
668    CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
669    CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
670
671    mmesa->ClearColor = mach64PackColor( mmesa->mach64Screen->cpp,
672                                         c[0], c[1], c[2], c[3] );
673 }
674
675 static void mach64DDLogicOpCode( struct gl_context *ctx, GLenum opcode )
676 {
677    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
678    
679    if ( ctx->Color.ColorLogicOpEnabled ) {
680       FLUSH_BATCH( mmesa );
681
682       FALLBACK( mmesa, MACH64_FALLBACK_LOGICOP, opcode != GL_COPY);
683    }
684 }
685
686 void mach64SetCliprects( struct gl_context *ctx, GLenum mode )
687 {
688    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
689    __DRIdrawable *dPriv = mmesa->driDrawable;
690
691    switch ( mode ) {
692    case GL_FRONT_LEFT:
693       mmesa->numClipRects = dPriv->numClipRects;
694       mmesa->pClipRects = dPriv->pClipRects;
695       mmesa->drawX = dPriv->x;
696       mmesa->drawY = dPriv->y;
697       break;
698    case GL_BACK_LEFT:
699       if ( dPriv->numBackClipRects == 0 ) {
700          mmesa->numClipRects = dPriv->numClipRects;
701          mmesa->pClipRects = dPriv->pClipRects;
702          mmesa->drawX = dPriv->x;
703          mmesa->drawY = dPriv->y;
704       } else {
705          mmesa->numClipRects = dPriv->numBackClipRects;
706          mmesa->pClipRects = dPriv->pBackClipRects;
707          mmesa->drawX = dPriv->backX;
708          mmesa->drawY = dPriv->backY;
709       }
710       break;
711    default:
712       return;
713    }
714
715    mach64UpdateClipping( ctx );
716
717    mmesa->dirty |= MACH64_UPLOAD_CLIPRECTS;
718 }
719
720 static void mach64DDDrawBuffer( struct gl_context *ctx, GLenum mode )
721 {
722    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
723
724    FLUSH_BATCH( mmesa );
725
726    if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
727       /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
728       FALLBACK( mmesa, MACH64_FALLBACK_DRAW_BUFFER, GL_TRUE );
729       return;
730    }
731
732    switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
733    case BUFFER_FRONT_LEFT:
734       FALLBACK( mmesa, MACH64_FALLBACK_DRAW_BUFFER, GL_FALSE );
735       mach64SetCliprects( ctx, GL_FRONT_LEFT );
736       if (MACH64_DEBUG & DEBUG_VERBOSE_MSG)
737          fprintf(stderr,"%s: BUFFER_BIT_FRONT_LEFT\n", __FUNCTION__);
738       break;
739    case BUFFER_BACK_LEFT:
740       FALLBACK( mmesa, MACH64_FALLBACK_DRAW_BUFFER, GL_FALSE );
741       mach64SetCliprects( ctx, GL_BACK_LEFT );
742       if (MACH64_DEBUG & DEBUG_VERBOSE_MSG)
743          fprintf(stderr,"%s: BUFFER_BIT_BACK_LEFT\n", __FUNCTION__);
744       break;
745    default:
746       FALLBACK( mmesa, MACH64_FALLBACK_DRAW_BUFFER, GL_TRUE );
747       if (MACH64_DEBUG & DEBUG_VERBOSE_MSG)
748          fprintf(stderr,"%s: fallback (mode=%d)\n", __FUNCTION__, mode);
749       break;
750    }
751
752    mmesa->setup.dst_off_pitch = (((mmesa->drawPitch/8) << 22) |
753                                  (mmesa->drawOffset >> 3));
754
755    mmesa->dirty |= MACH64_UPLOAD_DST_OFF_PITCH;
756 }
757
758 static void mach64DDReadBuffer( struct gl_context *ctx, GLenum mode )
759 {
760    /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
761 }
762
763 /* =============================================================
764  * State enable/disable
765  */
766
767 static void mach64DDEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
768 {
769    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
770
771    if ( MACH64_DEBUG & DEBUG_VERBOSE_API ) {
772       fprintf( stderr, "%s( %s = %s )\n",
773                __FUNCTION__, _mesa_lookup_enum_by_nr( cap ),
774                state ? "GL_TRUE" : "GL_FALSE" );
775    }
776
777    switch ( cap ) {
778    case GL_ALPHA_TEST:
779       FLUSH_BATCH( mmesa );
780       mmesa->new_state |= MACH64_NEW_ALPHA;
781       break;
782
783    case GL_BLEND:
784       FLUSH_BATCH( mmesa );
785       mmesa->new_state |= MACH64_NEW_ALPHA;
786
787       /* enable(GL_BLEND) affects ColorLogicOpEnabled.
788        */
789       FALLBACK( mmesa, MACH64_FALLBACK_LOGICOP,
790                 (ctx->Color.ColorLogicOpEnabled &&
791                  ctx->Color.LogicOp != GL_COPY));
792       break;
793
794    case GL_CULL_FACE:
795       FLUSH_BATCH( mmesa );
796       mmesa->new_state |= MACH64_NEW_CULL;
797       break;
798
799    case GL_DEPTH_TEST:
800       FLUSH_BATCH( mmesa );
801       mmesa->new_state |= MACH64_NEW_DEPTH;
802       break;
803
804    case GL_DITHER:
805       do {
806          GLuint s = mmesa->setup.scale_3d_cntl;
807          FLUSH_BATCH( mmesa );
808
809          if ( ctx->Color.DitherFlag ) {
810             /* Dithering causes problems w/ 24bpp depth */
811             if ( mmesa->mach64Screen->cpp == 4 )
812                s |=  MACH64_ROUND_EN;
813             else
814                s |=  MACH64_DITHER_EN;
815          } else {
816             s &= ~MACH64_DITHER_EN;
817             s &= ~MACH64_ROUND_EN;
818          }
819
820          if ( mmesa->setup.scale_3d_cntl != s ) {
821             mmesa->setup.scale_3d_cntl = s;
822             mmesa->dirty |= ( MACH64_UPLOAD_SCALE_3D_CNTL );
823          }
824       } while (0);
825       break;
826
827    case GL_FOG:
828       FLUSH_BATCH( mmesa );
829       mmesa->new_state |= MACH64_NEW_FOG;
830       break;
831
832    case GL_INDEX_LOGIC_OP:
833    case GL_COLOR_LOGIC_OP:
834       FLUSH_BATCH( mmesa );
835       FALLBACK( mmesa, MACH64_FALLBACK_LOGICOP,
836                 state && ctx->Color.LogicOp != GL_COPY );
837       break;
838
839    case GL_LIGHTING:
840       mach64UpdateSpecularLighting(ctx);
841       break;
842
843    case GL_SCISSOR_TEST:
844       FLUSH_BATCH( mmesa );
845       mmesa->scissor = state;
846       mmesa->new_state |= MACH64_NEW_CLIP;
847       break;
848
849    case GL_STENCIL_TEST:
850       FLUSH_BATCH( mmesa );
851       FALLBACK( mmesa, MACH64_FALLBACK_STENCIL, state );
852       break;
853
854    case GL_TEXTURE_1D:
855    case GL_TEXTURE_2D:
856    case GL_TEXTURE_3D:
857       FLUSH_BATCH( mmesa );
858       mmesa->new_state |= MACH64_NEW_TEXTURE;
859       break;
860
861    default:
862       return;
863    }
864 }
865
866 /* =============================================================
867  * Render mode
868  */
869
870 static void mach64DDRenderMode( struct gl_context *ctx, GLenum mode )
871 {
872    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
873    FALLBACK( mmesa, MACH64_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
874 }
875
876 /* =============================================================
877  * State initialization, management
878  */
879
880 static void mach64DDPrintDirty( const char *msg, GLuint state )
881 {
882    fprintf( stderr,
883             "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s\n",
884             msg,
885             state,
886             (state & MACH64_UPLOAD_DST_OFF_PITCH) ? "dst_off_pitch, " : "",
887             (state & MACH64_UPLOAD_Z_ALPHA_CNTL)  ? "z_alpha_cntl, " : "",
888             (state & MACH64_UPLOAD_SCALE_3D_CNTL) ? "scale_3d_cntl, " : "",
889             (state & MACH64_UPLOAD_DP_FOG_CLR)    ? "dp_fog_clr, " : "",
890             (state & MACH64_UPLOAD_DP_WRITE_MASK) ? "dp_write_mask, " : "",
891             (state & MACH64_UPLOAD_DP_PIX_WIDTH)  ? "dp_pix_width, " : "",
892             (state & MACH64_UPLOAD_SETUP_CNTL)    ? "setup_cntl, " : "",
893             (state & MACH64_UPLOAD_MISC)          ? "misc, " : "",
894             (state & MACH64_UPLOAD_TEXTURE)       ? "texture, " : "",
895             (state & MACH64_UPLOAD_TEX0IMAGE)     ? "tex0 image, " : "",
896             (state & MACH64_UPLOAD_TEX1IMAGE)     ? "tex1 image, " : "",
897             (state & MACH64_UPLOAD_CLIPRECTS)     ? "cliprects, " : "" );
898 }
899
900 /*
901  * Load the current context's state into the hardware.
902  *
903  * NOTE: Be VERY careful about ensuring the context state is marked for
904  * upload, the only place it shouldn't be uploaded is when the setup
905  * state has changed in ReducedPrimitiveChange as this comes right after
906  * a state update.
907  *
908  * Blits of any type should always upload the context and masks after
909  * they are done.
910  */
911 void mach64EmitHwStateLocked( mach64ContextPtr mmesa )
912 {
913    drm_mach64_sarea_t *sarea = mmesa->sarea;
914    drm_mach64_context_regs_t *regs = &(mmesa->setup);
915    mach64TexObjPtr t0 = mmesa->CurrentTexObj[0];
916    mach64TexObjPtr t1 = mmesa->CurrentTexObj[1];
917
918    if ( MACH64_DEBUG & DEBUG_VERBOSE_MSG ) {
919       mach64DDPrintDirty( __FUNCTION__, mmesa->dirty );
920    }
921
922    if ( t0 && t1 && mmesa->mach64Screen->numTexHeaps > 1 ) {
923       if (t0->heap != t1->heap || 
924              (mmesa->dirty & MACH64_UPLOAD_TEX0IMAGE) ||
925              (mmesa->dirty & MACH64_UPLOAD_TEX1IMAGE))
926          mach64UploadMultiTexImages( mmesa, t0, t1 );
927    } else {
928       if ( mmesa->dirty & MACH64_UPLOAD_TEX0IMAGE ) {
929          if ( t0 ) mach64UploadTexImages( mmesa, t0 );
930       }
931       if ( mmesa->dirty & MACH64_UPLOAD_TEX1IMAGE ) {
932          if ( t1 ) mach64UploadTexImages( mmesa, t1 );
933       }
934    }
935
936    if ( mmesa->dirty & (MACH64_UPLOAD_CONTEXT | MACH64_UPLOAD_MISC) ) {
937       memcpy( &sarea->context_state, regs,
938               MACH64_NR_CONTEXT_REGS * sizeof(GLuint) );
939    }
940
941    if ( mmesa->dirty & MACH64_UPLOAD_TEXTURE ) {
942       mach64EmitTexStateLocked( mmesa, t0, t1 );
943    }
944
945    sarea->vertsize = mmesa->vertex_size;
946
947    /* Turn off the texture cache flushing.
948     */
949    mmesa->setup.tex_cntl &= ~MACH64_TEX_CACHE_FLUSH;
950
951    sarea->dirty |= mmesa->dirty;
952
953    mmesa->dirty &= MACH64_UPLOAD_CLIPRECTS;
954 }
955
956 static void mach64DDPrintState( const char *msg, GLuint flags )
957 {
958    fprintf( stderr,
959             "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
960             msg,
961             flags,
962             (flags & MACH64_NEW_CONTEXT)        ? "context, " : "",
963             (flags & MACH64_NEW_ALPHA)          ? "alpha, " : "",
964             (flags & MACH64_NEW_DEPTH)          ? "depth, " : "",
965             (flags & MACH64_NEW_FOG)            ? "fog, " : "",
966             (flags & MACH64_NEW_CLIP)           ? "clip, " : "",
967             (flags & MACH64_NEW_TEXTURE)        ? "texture, " : "",
968             (flags & MACH64_NEW_CULL)           ? "cull, " : "",
969             (flags & MACH64_NEW_MASKS)          ? "masks, " : "",
970             (flags & MACH64_NEW_WINDOW)         ? "window, " : "" );
971 }
972
973 /* Update the hardware state */
974 void mach64DDUpdateHWState( struct gl_context *ctx )
975 {
976    mach64ContextPtr mmesa = MACH64_CONTEXT(ctx);
977    int new_state = mmesa->new_state;
978
979    if ( MACH64_DEBUG & DEBUG_VERBOSE_MSG ) {
980       fprintf( stderr, "%s:\n", __FUNCTION__ );
981    }
982
983    if ( new_state )
984    {
985       FLUSH_BATCH( mmesa );
986
987       mmesa->new_state = 0;
988
989       if ( MACH64_DEBUG & DEBUG_VERBOSE_MSG )
990          mach64DDPrintState( __FUNCTION__, new_state );
991
992       /* Update the various parts of the context's state.
993        */
994       if ( new_state & MACH64_NEW_ALPHA )
995          mach64UpdateAlphaMode( ctx );
996
997       if ( new_state & MACH64_NEW_DEPTH )
998          mach64UpdateZMode( ctx );
999
1000       if ( new_state & MACH64_NEW_FOG )
1001          mach64UpdateFogAttrib( ctx );
1002
1003       if ( new_state & MACH64_NEW_CLIP )
1004          mach64UpdateClipping( ctx );
1005
1006       if ( new_state & MACH64_NEW_WINDOW )
1007          mach64CalcViewport( ctx );
1008
1009       if ( new_state & MACH64_NEW_CULL )
1010          mach64UpdateCull( ctx );
1011
1012       if ( new_state & MACH64_NEW_MASKS )
1013          mach64UpdateMasks( ctx );
1014
1015       if ( new_state & MACH64_NEW_TEXTURE )
1016          mach64UpdateTextureState( ctx );
1017    }
1018 }
1019
1020
1021 static void mach64DDInvalidateState( struct gl_context *ctx, GLuint new_state )
1022 {
1023    _swrast_InvalidateState( ctx, new_state );
1024    _swsetup_InvalidateState( ctx, new_state );
1025    _vbo_InvalidateState( ctx, new_state );
1026    _tnl_InvalidateState( ctx, new_state );
1027    MACH64_CONTEXT(ctx)->NewGLState |= new_state;
1028 }
1029
1030
1031 /* Initialize the context's hardware state */
1032 void mach64DDInitState( mach64ContextPtr mmesa )
1033 {
1034    GLuint format;
1035
1036    switch ( mmesa->mach64Screen->cpp ) {
1037    case 2:
1038       format = MACH64_DATATYPE_RGB565;
1039       break;
1040    case 4:
1041       format = MACH64_DATATYPE_ARGB8888;
1042       break;
1043    default:
1044       fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" );
1045       exit( -1 );
1046    }
1047
1048    /* Always have a 16-bit depth buffer
1049     * but Z coordinates are specified in 16.1 format to the setup engine.
1050     */
1051    mmesa->depth_scale = 2.0;
1052
1053    mmesa->ClearColor = 0x00000000;
1054    mmesa->ClearDepth = 0x0000ffff;
1055
1056    mmesa->Fallback = 0;
1057
1058    if ( mmesa->glCtx->Visual.doubleBufferMode ) {
1059       mmesa->drawOffset = mmesa->readOffset = mmesa->mach64Screen->backOffset;
1060       mmesa->drawPitch  = mmesa->readPitch  = mmesa->mach64Screen->backPitch;
1061    } else {
1062       mmesa->drawOffset = mmesa->readOffset = mmesa->mach64Screen->frontOffset;
1063       mmesa->drawPitch  = mmesa->readPitch  = mmesa->mach64Screen->frontPitch;
1064    }
1065
1066    /* Harware state:
1067     */
1068    mmesa->setup.dst_off_pitch = (((mmesa->drawPitch/8) << 22) |
1069                                  (mmesa->drawOffset >> 3));
1070
1071    mmesa->setup.z_off_pitch = (((mmesa->mach64Screen->depthPitch/8) << 22) |
1072                                (mmesa->mach64Screen->depthOffset >> 3));
1073
1074    mmesa->setup.z_cntl = (MACH64_Z_TEST_LESS |
1075                           MACH64_Z_MASK_EN);
1076
1077    mmesa->setup.alpha_tst_cntl = (MACH64_ALPHA_TEST_ALWAYS |
1078                                   MACH64_ALPHA_DST_SRCALPHA |
1079                                   MACH64_ALPHA_TST_SRC_TEXEL |
1080                                   (0 << MACH64_REF_ALPHA_SHIFT));
1081
1082    mmesa->setup.scale_3d_cntl = (MACH64_SCALE_PIX_EXPAND_DYNAMIC_RANGE |
1083                                  /*  MACH64_SCALE_DITHER_ERROR_DIFFUSE | */
1084                                  MACH64_SCALE_DITHER_2D_TABLE |
1085                                  /*  MACH64_DITHER_INIT_CURRENT | */
1086                                  MACH64_DITHER_INIT_RESET |
1087                                  MACH64_SCALE_3D_FCN_SHADE |
1088                                  MACH64_ALPHA_FOG_DIS |
1089                                  MACH64_ALPHA_BLEND_SRC_ONE |
1090                                  MACH64_ALPHA_BLEND_DST_ZERO |
1091                                  MACH64_TEX_LIGHT_FCN_MODULATE |
1092                                  MACH64_MIP_MAP_DISABLE |
1093                                  MACH64_BILINEAR_TEX_EN |
1094                                  MACH64_TEX_BLEND_FCN_LINEAR);
1095
1096    /* GL spec says dithering initially enabled, but dithering causes
1097     * problems w/ 24bpp depth
1098     */
1099    if ( mmesa->mach64Screen->cpp == 4 )
1100       mmesa->setup.scale_3d_cntl |= MACH64_ROUND_EN;
1101    else
1102       mmesa->setup.scale_3d_cntl |= MACH64_DITHER_EN;
1103
1104    mmesa->setup.sc_left_right = 0x1fff0000;
1105    mmesa->setup.sc_top_bottom = 0x3fff0000;
1106
1107    mmesa->setup.dp_fog_clr    = 0x00ffffff;
1108    mmesa->setup.dp_write_mask = 0xffffffff;
1109
1110    mmesa->setup.dp_pix_width = ((format << 0) |
1111                                 (format << 4) |
1112                                 (format << 8) |
1113                                 (format << 16) |
1114                                 (format << 28));
1115
1116    mmesa->setup.dp_mix = (MACH64_BKGD_MIX_S |
1117                           MACH64_FRGD_MIX_S);
1118    mmesa->setup.dp_src = (MACH64_BKGD_SRC_3D |
1119                           MACH64_FRGD_SRC_3D |
1120                           MACH64_MONO_SRC_ONE);
1121
1122    mmesa->setup.clr_cmp_cntl  = 0x00000000;
1123    mmesa->setup.gui_traj_cntl = (MACH64_DST_X_LEFT_TO_RIGHT |
1124                                  MACH64_DST_Y_TOP_TO_BOTTOM);
1125
1126    mmesa->setup.setup_cntl = (MACH64_FLAT_SHADE_OFF |
1127                               MACH64_SOLID_MODE_OFF |
1128                               MACH64_LOG_MAX_INC_ADJ);
1129    mmesa->setup.setup_cntl = 0;
1130
1131    mmesa->setup.tex_size_pitch = 0x00000000;
1132
1133    mmesa->setup.tex_cntl = ((0 << MACH64_LOD_BIAS_SHIFT) |
1134                             (0 << MACH64_COMP_FACTOR_SHIFT) |
1135                             MACH64_COMP_COMBINE_MODULATE |
1136                             MACH64_COMP_BLEND_NEAREST |
1137                             MACH64_COMP_FILTER_NEAREST |
1138                             /* MACH64_TEXTURE_TILING | */
1139 #ifdef MACH64_PREMULT_TEXCOORDS
1140                             MACH64_TEX_ST_DIRECT | 
1141 #endif
1142                             MACH64_TEX_SRC_LOCAL |
1143                             MACH64_TEX_UNCOMPRESSED |
1144                             MACH64_TEX_CACHE_FLUSH |
1145                             MACH64_TEX_CACHE_SIZE_4K);
1146
1147    mmesa->setup.secondary_tex_off = 0x00000000;
1148    mmesa->setup.tex_offset = 0x00000000;
1149
1150    mmesa->new_state = MACH64_NEW_ALL;
1151 }
1152
1153 /* Initialize the driver's state functions.
1154   */
1155 void mach64DDInitStateFuncs( struct gl_context *ctx )
1156 {
1157    ctx->Driver.UpdateState              = mach64DDInvalidateState;
1158
1159    ctx->Driver.ClearColor               = mach64DDClearColor;
1160    ctx->Driver.DrawBuffer               = mach64DDDrawBuffer;
1161    ctx->Driver.ReadBuffer               = mach64DDReadBuffer;
1162
1163    ctx->Driver.ColorMask                = mach64DDColorMask;
1164    ctx->Driver.AlphaFunc                = mach64DDAlphaFunc;
1165    ctx->Driver.BlendEquationSeparate    = mach64DDBlendEquationSeparate;
1166    ctx->Driver.BlendFuncSeparate        = mach64DDBlendFuncSeparate;
1167    ctx->Driver.ClearDepth               = mach64DDClearDepth;
1168    ctx->Driver.CullFace                 = mach64DDCullFace;
1169    ctx->Driver.FrontFace                = mach64DDFrontFace;
1170    ctx->Driver.DepthFunc                = mach64DDDepthFunc;
1171    ctx->Driver.DepthMask                = mach64DDDepthMask;
1172    ctx->Driver.Enable                   = mach64DDEnable;
1173    ctx->Driver.Fogfv                    = mach64DDFogfv;
1174    ctx->Driver.Hint                     = NULL;
1175    ctx->Driver.Lightfv                  = NULL;
1176    ctx->Driver.LightModelfv             = mach64DDLightModelfv;
1177    ctx->Driver.LogicOpcode              = mach64DDLogicOpCode;
1178    ctx->Driver.PolygonMode              = NULL;
1179    ctx->Driver.PolygonStipple           = NULL;
1180    ctx->Driver.RenderMode               = mach64DDRenderMode;
1181    ctx->Driver.Scissor                  = mach64DDScissor;
1182    ctx->Driver.ShadeModel               = mach64DDShadeModel;
1183    
1184    ctx->Driver.DepthRange               = mach64DepthRange;
1185    ctx->Driver.Viewport                 = mach64Viewport;
1186 }