patch to import Jon Smirl's work from Bitkeeper
[mesa.git] / src / mesa / drivers / dri / mga / mgastate.c
1 /*
2 * Copyright 2000-2001 VA Linux Systems, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Keith Whitwell <keith@tungstengraphics.com>
26 */
27 /* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.13 2002/10/30 12:51:36 alanh Exp $ */
28
29
30 #include "mtypes.h"
31 #include "colormac.h"
32 #include "dd.h"
33
34 #include "mm.h"
35 #include "mgacontext.h"
36 #include "mgadd.h"
37 #include "mgastate.h"
38 #include "mgatex.h"
39 #include "mgavb.h"
40 #include "mgatris.h"
41 #include "mgaioctl.h"
42 #include "mgaregs.h"
43
44 #include "swrast/swrast.h"
45 #include "array_cache/acache.h"
46 #include "tnl/tnl.h"
47 #include "tnl/t_context.h"
48 #include "tnl/t_pipeline.h"
49 #include "swrast_setup/swrast_setup.h"
50
51
52 static void updateSpecularLighting( GLcontext *ctx );
53
54
55 /* Some outstanding problems with accelerating logic ops...
56 */
57 #if defined(ACCEL_ROP)
58 static const GLuint mgarop_NoBLK[16] = {
59 DC_atype_rpl | 0x00000000, DC_atype_rstr | 0x00080000,
60 DC_atype_rstr | 0x00040000, DC_atype_rpl | 0x000c0000,
61 DC_atype_rstr | 0x00020000, DC_atype_rstr | 0x000a0000,
62 DC_atype_rstr | 0x00060000, DC_atype_rstr | 0x000e0000,
63 DC_atype_rstr | 0x00010000, DC_atype_rstr | 0x00090000,
64 DC_atype_rstr | 0x00050000, DC_atype_rstr | 0x000d0000,
65 DC_atype_rpl | 0x00030000, DC_atype_rstr | 0x000b0000,
66 DC_atype_rstr | 0x00070000, DC_atype_rpl | 0x000f0000
67 };
68 #endif
69
70
71 /* =============================================================
72 * Alpha blending
73 */
74
75 static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
76 {
77 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
78 GLubyte refByte;
79 GLuint a;
80
81 CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
82
83 switch ( func ) {
84 case GL_NEVER:
85 a = AC_atmode_alt;
86 refByte = 0;
87 break;
88 case GL_LESS:
89 a = AC_atmode_alt;
90 break;
91 case GL_GEQUAL:
92 a = AC_atmode_agte;
93 break;
94 case GL_LEQUAL:
95 a = AC_atmode_alte;
96 break;
97 case GL_GREATER:
98 a = AC_atmode_agt;
99 break;
100 case GL_NOTEQUAL:
101 a = AC_atmode_ane;
102 break;
103 case GL_EQUAL:
104 a = AC_atmode_ae;
105 break;
106 case GL_ALWAYS:
107 a = AC_atmode_noacmp;
108 break;
109 default:
110 a = 0;
111 break;
112 }
113
114 FLUSH_BATCH( mmesa );
115 mmesa->hw.alpha_func = a | MGA_FIELD( AC_atref, refByte );
116 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
117 }
118
119 static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode)
120 {
121 FLUSH_BATCH( MGA_CONTEXT(ctx) );
122
123 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
124 * manner.
125 */
126 FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
127 (ctx->Color.ColorLogicOpEnabled &&
128 ctx->Color.LogicOp != GL_COPY));
129 }
130
131 static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
132 {
133 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
134 mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
135 GLuint src;
136 GLuint dst;
137
138 switch (ctx->Color.BlendSrcRGB) {
139 case GL_ZERO:
140 src = AC_src_zero; break;
141 case GL_SRC_ALPHA:
142 src = AC_src_src_alpha; break;
143 case GL_ONE:
144 default: /* never happens */
145 src = AC_src_one; break;
146 case GL_DST_COLOR:
147 src = AC_src_dst_color; break;
148 case GL_ONE_MINUS_DST_COLOR:
149 src = AC_src_om_dst_color; break;
150 case GL_ONE_MINUS_SRC_ALPHA:
151 src = AC_src_om_src_alpha; break;
152 case GL_DST_ALPHA:
153 src = (mgaScreen->cpp == 4)
154 ? AC_src_dst_alpha : AC_src_one;
155 break;
156 case GL_ONE_MINUS_DST_ALPHA:
157 src = (mgaScreen->cpp == 4)
158 ? AC_src_om_dst_alpha : AC_src_zero;
159 break;
160 case GL_SRC_ALPHA_SATURATE:
161 src = (ctx->Visual.alphaBits > 0)
162 ? AC_src_src_alpha_sat : AC_src_zero;
163 break;
164 }
165
166 switch (ctx->Color.BlendDstRGB) {
167 case GL_SRC_ALPHA:
168 dst = AC_dst_src_alpha; break;
169 case GL_ONE_MINUS_SRC_ALPHA:
170 dst = AC_dst_om_src_alpha; break;
171 default: /* never happens */
172 case GL_ZERO:
173 dst = AC_dst_zero; break;
174 case GL_ONE:
175 dst = AC_dst_one; break;
176 case GL_SRC_COLOR:
177 dst = AC_dst_src_color; break;
178 case GL_ONE_MINUS_SRC_COLOR:
179 dst = AC_dst_om_src_color; break;
180 case GL_DST_ALPHA:
181 dst = (mgaScreen->cpp == 4)
182 ? AC_dst_dst_alpha : AC_dst_one;
183 break;
184 case GL_ONE_MINUS_DST_ALPHA:
185 dst = (mgaScreen->cpp == 4)
186 ? AC_dst_om_dst_alpha : AC_dst_zero;
187 break;
188 }
189
190 FLUSH_BATCH( mmesa );
191 mmesa->hw.blend_func = (src | dst);
192 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
193 }
194
195 static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
196 GLenum dfactorRGB, GLenum sfactorA,
197 GLenum dfactorA )
198 {
199 mgaDDBlendFunc( ctx, sfactorRGB, dfactorRGB );
200 }
201
202
203 /* =============================================================
204 * Depth testing
205 */
206
207 static void mgaDDDepthFunc(GLcontext *ctx, GLenum func)
208 {
209 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
210 int zmode;
211
212 switch (func) {
213 case GL_NEVER:
214 /* can't do this in h/w, we'll use a s/w fallback */
215 FALLBACK (ctx, MGA_FALLBACK_DEPTH, ctx->Depth.Test);
216
217 /* FALLTHROUGH */
218 case GL_ALWAYS:
219 zmode = DC_zmode_nozcmp; break;
220 case GL_LESS:
221 zmode = DC_zmode_zlt; break;
222 case GL_LEQUAL:
223 zmode = DC_zmode_zlte; break;
224 case GL_EQUAL:
225 zmode = DC_zmode_ze; break;
226 case GL_GREATER:
227 zmode = DC_zmode_zgt; break;
228 case GL_GEQUAL:
229 zmode = DC_zmode_zgte; break;
230 case GL_NOTEQUAL:
231 zmode = DC_zmode_zne; break;
232 default:
233 zmode = 0; break;
234 }
235
236 FLUSH_BATCH( mmesa );
237 mmesa->hw.zmode &= DC_zmode_MASK;
238 mmesa->hw.zmode |= zmode;
239 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
240 }
241
242 static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag)
243 {
244 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
245
246
247 FLUSH_BATCH( mmesa );
248 mmesa->hw.zmode &= DC_atype_MASK;
249 mmesa->hw.zmode |= (flag) ? DC_atype_zi : DC_atype_i;
250 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
251 }
252
253
254 static void mgaDDClearDepth(GLcontext *ctx, GLclampd d)
255 {
256 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
257
258 /* Select the Z depth. The ~ is used because the _MASK values in the
259 * MGA driver are used to mask OFF the selected bits. In this case,
260 * we want to mask off everything except the MA_zwidth bits.
261 */
262 switch (mmesa->setup.maccess & ~MA_zwidth_MASK) {
263 case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break;
264 case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break;
265 case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break;
266 default: return;
267 }
268 }
269
270
271 /* =============================================================
272 * Fog
273 */
274
275
276 static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
277 {
278 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
279
280 if (pname == GL_FOG_COLOR) {
281 GLuint color = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F),
282 (GLubyte)(ctx->Fog.Color[1]*255.0F),
283 (GLubyte)(ctx->Fog.Color[2]*255.0F));
284
285 MGA_STATECHANGE(mmesa, MGA_UPLOAD_CONTEXT);
286 mmesa->setup.fogcolor = color;
287 }
288 }
289
290
291 /* =============================================================
292 * Scissoring
293 */
294
295
296 void mgaUpdateClipping(const GLcontext *ctx)
297 {
298 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
299
300 if (mmesa->driDrawable)
301 {
302 int x1 = mmesa->driDrawable->x + ctx->Scissor.X;
303 int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h
304 - (ctx->Scissor.Y + ctx->Scissor.Height);
305 int x2 = x1 + ctx->Scissor.Width - 1;
306 int y2 = y1 + ctx->Scissor.Height - 1;
307
308 if (x1 < 0) x1 = 0;
309 if (y1 < 0) y1 = 0;
310 if (x2 < 0) x2 = 0;
311 if (y2 < 0) y2 = 0;
312
313 mmesa->scissor_rect.x1 = x1;
314 mmesa->scissor_rect.y1 = y1;
315 mmesa->scissor_rect.x2 = x2;
316 mmesa->scissor_rect.y2 = y2;
317
318 mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
319 }
320 }
321
322
323 static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y,
324 GLsizei w, GLsizei h )
325 {
326 if ( ctx->Scissor.Enabled ) {
327 FLUSH_BATCH( MGA_CONTEXT(ctx) ); /* don't pipeline cliprect changes */
328 mgaUpdateClipping( ctx );
329 }
330 }
331
332
333 /* =============================================================
334 * Culling
335 */
336
337
338 #define _CULL_DISABLE 0
339 #define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16))
340 #define _CULL_POSITIVE (1<<11)
341
342 static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
343 {
344 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
345
346
347 FLUSH_BATCH( mmesa );
348 if (ctx->Polygon.CullFlag &&
349 ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK)
350 {
351 mmesa->hw.cull = _CULL_NEGATIVE;
352
353 if (ctx->Polygon.CullFaceMode == GL_FRONT)
354 mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);
355
356 if (ctx->Polygon.FrontFace != GL_CCW)
357 mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);
358
359 mmesa->hw.cull_dualtex = mmesa->hw.cull ^
360 (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* warp bug? */
361 }
362 else {
363 mmesa->hw.cull = _CULL_DISABLE;
364 mmesa->hw.cull_dualtex = _CULL_DISABLE;
365 }
366
367 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
368 }
369
370
371 /* =============================================================
372 * Masks
373 */
374
375 static void mgaDDColorMask(GLcontext *ctx,
376 GLboolean r, GLboolean g,
377 GLboolean b, GLboolean a )
378 {
379 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
380 mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
381
382
383 GLuint mask = mgaPackColor(mgaScreen->cpp,
384 ctx->Color.ColorMask[RCOMP],
385 ctx->Color.ColorMask[GCOMP],
386 ctx->Color.ColorMask[BCOMP],
387 ctx->Color.ColorMask[ACOMP]);
388
389 if (mgaScreen->cpp == 2)
390 mask = mask | (mask << 16);
391
392 if (mmesa->setup.plnwt != mask) {
393 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
394 mmesa->setup.plnwt = mask;
395 }
396 }
397
398
399 /* =============================================================
400 * Polygon state
401 */
402
403 static int mgaStipples[16] = {
404 0xffff1, /* See above note */
405 0xa5a5,
406 0x5a5a,
407 0xa0a0,
408 0x5050,
409 0x0a0a,
410 0x0505,
411 0x8020,
412 0x0401,
413 0x1040,
414 0x0208,
415 0x0802,
416 0x4010,
417 0x0104,
418 0x2080,
419 0x0000
420 };
421
422 /**
423 * The MGA supports a subset of possible 4x4 stipples natively, GL
424 * wants 32x32. Fortunately stipple is usually a repeating pattern.
425 *
426 * \param ctx GL rendering context to be affected
427 * \param mask Pointer to the 32x32 stipple mask
428 *
429 * \note the fully opaque pattern (0xffff) has been disabled in order
430 * to work around a conformance issue.
431 */
432
433 static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
434 {
435 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
436 const GLubyte *m = mask;
437 GLubyte p[4];
438 int i,j,k;
439 int active = (ctx->Polygon.StippleFlag &&
440 mmesa->raster_primitive == GL_TRIANGLES);
441 GLuint stipple;
442
443 FLUSH_BATCH(mmesa);
444 mmesa->haveHwStipple = 0;
445
446 if (active) {
447 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
448 mmesa->setup.dwgctl &= ~(0xf<<20);
449 }
450
451 p[0] = mask[0] & 0xf; p[0] |= p[0] << 4;
452 p[1] = mask[4] & 0xf; p[1] |= p[1] << 4;
453 p[2] = mask[8] & 0xf; p[2] |= p[2] << 4;
454 p[3] = mask[12] & 0xf; p[3] |= p[3] << 4;
455
456 for (k = 0 ; k < 8 ; k++)
457 for (j = 0 ; j < 4; j++)
458 for (i = 0 ; i < 4 ; i++)
459 if (*m++ != p[j]) {
460 return;
461 }
462
463 stipple = ( ((p[0] & 0xf) << 0) |
464 ((p[1] & 0xf) << 4) |
465 ((p[2] & 0xf) << 8) |
466 ((p[3] & 0xf) << 12) );
467
468 for (i = 0 ; i < 16 ; i++)
469 if (mgaStipples[i] == stipple) {
470 mmesa->poly_stipple = i<<20;
471 mmesa->haveHwStipple = 1;
472 break;
473 }
474
475 if (active) {
476 mmesa->setup.dwgctl &= ~(0xf<<20);
477 mmesa->setup.dwgctl |= mmesa->poly_stipple;
478 }
479 }
480
481
482 /* =============================================================
483 * Rendering attributes
484 *
485 * We really don't want to recalculate all this every time we bind a
486 * texture. These things shouldn't change all that often, so it makes
487 * sense to break them out of the core texture state update routines.
488 */
489
490 static void updateSpecularLighting( GLcontext *ctx )
491 {
492 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
493 unsigned int specen;
494
495 specen = (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
496 ctx->Light.Enabled) ? TMC_specen_enable : 0;
497
498 if ( specen != mmesa->hw.specen ) {
499 mmesa->hw.specen = specen;
500 mmesa->dirty |= MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1;
501
502 mgaChooseVertexState( ctx );
503 }
504 }
505
506
507 /* =============================================================
508 * Materials
509 */
510
511
512 static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname,
513 const GLfloat *param)
514 {
515 if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
516 FLUSH_BATCH( MGA_CONTEXT(ctx) );
517 updateSpecularLighting( ctx );
518 }
519 }
520
521
522 static void mgaDDShadeModel(GLcontext *ctx, GLenum mode)
523 {
524 /* FIXME: This used to FLUSH_BATCH and set MGA_NEW_TEXTURE in new_state,
525 * FIXME: so I'm not sure what to do here now.
526 */
527 }
528
529
530 /* =============================================================
531 * Stencil
532 */
533
534
535 static void mgaDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
536 GLuint mask)
537 {
538 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
539 GLuint stencil;
540 GLuint stencilctl;
541
542 stencil = (ref << S_sref_SHIFT) | (mask << S_smsk_SHIFT);
543 switch (func)
544 {
545 case GL_NEVER:
546 stencilctl = SC_smode_snever;
547 break;
548 case GL_LESS:
549 stencilctl = SC_smode_slt;
550 break;
551 case GL_LEQUAL:
552 stencilctl = SC_smode_slte;
553 break;
554 case GL_GREATER:
555 stencilctl = SC_smode_sgt;
556 break;
557 case GL_GEQUAL:
558 stencilctl = SC_smode_sgte;
559 break;
560 case GL_NOTEQUAL:
561 stencilctl = SC_smode_sne;
562 break;
563 case GL_EQUAL:
564 stencilctl = SC_smode_se;
565 break;
566 case GL_ALWAYS:
567 default:
568 stencilctl = SC_smode_salways;
569 break;
570 }
571
572 FLUSH_BATCH( mmesa );
573 mmesa->hw.stencil &= (S_sref_MASK & S_smsk_MASK);
574 mmesa->hw.stencil |= stencil;
575 mmesa->hw.stencilctl &= SC_smode_MASK;
576 mmesa->hw.stencilctl |= stencilctl;
577 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
578 }
579
580 static void mgaDDStencilMask(GLcontext *ctx, GLuint mask)
581 {
582 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
583
584 FLUSH_BATCH( mmesa );
585 mmesa->hw.stencil &= S_swtmsk_MASK;
586 mmesa->hw.stencil |= (mask << S_swtmsk_SHIFT);
587 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
588 }
589
590 static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
591 GLenum zpass)
592 {
593 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
594 GLuint stencilctl;
595
596 stencilctl = 0;
597 switch (ctx->Stencil.FailFunc[0])
598 {
599 case GL_KEEP:
600 stencilctl |= SC_sfailop_keep;
601 break;
602 case GL_ZERO:
603 stencilctl |= SC_sfailop_zero;
604 break;
605 case GL_REPLACE:
606 stencilctl |= SC_sfailop_replace;
607 break;
608 case GL_INCR:
609 stencilctl |= SC_sfailop_incrsat;
610 break;
611 case GL_DECR:
612 stencilctl |= SC_sfailop_decrsat;
613 break;
614 case GL_INCR_WRAP:
615 stencilctl |= SC_sfailop_incr;
616 break;
617 case GL_DECR_WRAP:
618 stencilctl |= SC_sfailop_decr;
619 break;
620 case GL_INVERT:
621 stencilctl |= SC_sfailop_invert;
622 break;
623 default:
624 break;
625 }
626
627 switch (ctx->Stencil.ZFailFunc[0])
628 {
629 case GL_KEEP:
630 stencilctl |= SC_szfailop_keep;
631 break;
632 case GL_ZERO:
633 stencilctl |= SC_szfailop_zero;
634 break;
635 case GL_REPLACE:
636 stencilctl |= SC_szfailop_replace;
637 break;
638 case GL_INCR:
639 stencilctl |= SC_szfailop_incrsat;
640 break;
641 case GL_DECR:
642 stencilctl |= SC_szfailop_decrsat;
643 break;
644 case GL_INCR_WRAP:
645 stencilctl |= SC_szfailop_incr;
646 break;
647 case GL_DECR_WRAP:
648 stencilctl |= SC_szfailop_decr;
649 break;
650 case GL_INVERT:
651 stencilctl |= SC_szfailop_invert;
652 break;
653 default:
654 break;
655 }
656
657 switch (ctx->Stencil.ZPassFunc[0])
658 {
659 case GL_KEEP:
660 stencilctl |= SC_szpassop_keep;
661 break;
662 case GL_ZERO:
663 stencilctl |= SC_szpassop_zero;
664 break;
665 case GL_REPLACE:
666 stencilctl |= SC_szpassop_replace;
667 break;
668 case GL_INCR:
669 stencilctl |= SC_szpassop_incrsat;
670 break;
671 case GL_DECR:
672 stencilctl |= SC_szpassop_decrsat;
673 break;
674 case GL_INVERT:
675 stencilctl |= SC_szpassop_invert;
676 break;
677 default:
678 break;
679 }
680
681 FLUSH_BATCH( mmesa );
682 mmesa->hw.stencilctl &= (SC_sfailop_MASK & SC_szfailop_MASK
683 & SC_szpassop_MASK);
684 mmesa->hw.stencilctl |= stencilctl;
685 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
686 }
687
688
689 /* =============================================================
690 * Window position and viewport transformation
691 */
692
693 void mgaCalcViewport( GLcontext *ctx )
694 {
695 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
696 const GLfloat *v = ctx->Viewport._WindowMap.m;
697 GLfloat *m = mmesa->hw_viewport;
698
699 /* See also mga_translate_vertex.
700 */
701 m[MAT_SX] = v[MAT_SX];
702 m[MAT_TX] = v[MAT_TX] + mmesa->drawX + SUBPIXEL_X;
703 m[MAT_SY] = - v[MAT_SY];
704 m[MAT_TY] = - v[MAT_TY] + mmesa->driDrawable->h + mmesa->drawY + SUBPIXEL_Y;
705 m[MAT_SZ] = v[MAT_SZ] * mmesa->depth_scale;
706 m[MAT_TZ] = v[MAT_TZ] * mmesa->depth_scale;
707
708 mmesa->SetupNewInputs = ~0;
709 }
710
711 static void mgaViewport( GLcontext *ctx,
712 GLint x, GLint y,
713 GLsizei width, GLsizei height )
714 {
715 mgaCalcViewport( ctx );
716 }
717
718 static void mgaDepthRange( GLcontext *ctx,
719 GLclampd nearval, GLclampd farval )
720 {
721 mgaCalcViewport( ctx );
722 }
723
724
725 /* =============================================================
726 * Miscellaneous
727 */
728
729 static void mgaDDClearColor(GLcontext *ctx,
730 const GLfloat color[4] )
731 {
732 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
733 GLubyte c[4];
734 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
735 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
736 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
737 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
738
739 mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->cpp,
740 c[0], c[1], c[2], c[3]);
741 }
742
743
744 /* Fallback to swrast for select and feedback.
745 */
746 static void mgaRenderMode( GLcontext *ctx, GLenum mode )
747 {
748 FALLBACK( ctx, MGA_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
749 }
750
751
752 static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode )
753 {
754 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
755
756 FLUSH_BATCH( mmesa );
757 #if defined(ACCEL_ROP)
758 mmesa->hw.rop = mgarop_NoBLK[ opcode & 0x0f ];
759 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
760 #else
761 FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
762 (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) );
763 #endif
764 }
765
766
767 static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa )
768 {
769 __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
770
771 if (driDrawable->numClipRects == 0) {
772 static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
773 mmesa->numClipRects = 1;
774 mmesa->pClipRects = &zeroareacliprect;
775 } else {
776 mmesa->numClipRects = driDrawable->numClipRects;
777 mmesa->pClipRects = driDrawable->pClipRects;
778 }
779 mmesa->drawX = driDrawable->x;
780 mmesa->drawY = driDrawable->y;
781
782 mmesa->setup.dstorg = mmesa->drawOffset;
783 mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
784 }
785
786
787 static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa )
788 {
789 __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
790
791 if (driDrawable->numBackClipRects == 0)
792 {
793 if (driDrawable->numClipRects == 0) {
794 static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
795 mmesa->numClipRects = 1;
796 mmesa->pClipRects = &zeroareacliprect;
797 } else {
798 mmesa->numClipRects = driDrawable->numClipRects;
799 mmesa->pClipRects = driDrawable->pClipRects;
800 }
801 mmesa->drawX = driDrawable->x;
802 mmesa->drawY = driDrawable->y;
803 } else {
804 mmesa->numClipRects = driDrawable->numBackClipRects;
805 mmesa->pClipRects = driDrawable->pBackClipRects;
806 mmesa->drawX = driDrawable->backX;
807 mmesa->drawY = driDrawable->backY;
808 }
809
810 mmesa->setup.dstorg = mmesa->drawOffset;
811 mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
812 }
813
814
815 void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
816 {
817 __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
818 MGASAREAPrivPtr sarea = mmesa->sarea;
819
820
821 DRI_VALIDATE_DRAWABLE_INFO(mmesa->driScreen, driDrawable);
822 mmesa->dirty_cliprects = 0;
823
824 if (mmesa->draw_buffer == MGA_FRONT)
825 mgaXMesaSetFrontClipRects( mmesa );
826 else
827 mgaXMesaSetBackClipRects( mmesa );
828
829 sarea->req_draw_buffer = mmesa->draw_buffer;
830
831 mgaUpdateClipping( mmesa->glCtx );
832 mgaCalcViewport( mmesa->glCtx );
833
834 mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
835 }
836
837
838 static void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode )
839 {
840 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
841
842 FLUSH_BATCH( mmesa );
843
844 /*
845 * _DrawDestMask is easier to cope with than <mode>.
846 */
847 switch ( ctx->Color._DrawDestMask ) {
848 case FRONT_LEFT_BIT:
849 mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset;
850 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
851 mmesa->draw_buffer = MGA_FRONT;
852 mgaXMesaSetFrontClipRects( mmesa );
853 FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE );
854 break;
855 case BACK_LEFT_BIT:
856 mmesa->setup.dstorg = mmesa->mgaScreen->backOffset;
857 mmesa->draw_buffer = MGA_BACK;
858 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
859 mgaXMesaSetBackClipRects( mmesa );
860 FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE );
861 break;
862 default:
863 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
864 FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE );
865 return;
866 }
867
868 /* We want to update the s/w rast state too so that r200SetBuffer()
869 * gets called.
870 */
871 _swrast_DrawBuffer(ctx, mode);
872 }
873
874
875 static void mgaDDReadBuffer(GLcontext *ctx, GLenum mode )
876 {
877 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
878 }
879
880
881 /* =============================================================
882 * State enable/disable
883 */
884
885
886 static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
887 {
888 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
889
890 switch(cap) {
891 case GL_ALPHA_TEST:
892 FLUSH_BATCH( mmesa );
893 mmesa->hw.alpha_func_enable = (state) ? ~0 : 0;
894 break;
895 case GL_BLEND:
896 FLUSH_BATCH( mmesa );
897 mmesa->hw.blend_func_enable = (state) ? ~0 : 0;
898
899 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
900 */
901 FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
902 (ctx->Color.ColorLogicOpEnabled &&
903 ctx->Color.LogicOp != GL_COPY));
904 break;
905 case GL_DEPTH_TEST:
906 FLUSH_BATCH( mmesa );
907 FALLBACK (ctx, MGA_FALLBACK_DEPTH,
908 ctx->Depth.Func == GL_NEVER && ctx->Depth.Test);
909 break;
910
911 case GL_SCISSOR_TEST:
912 FLUSH_BATCH( mmesa );
913 mmesa->scissor = state;
914 mgaUpdateClipping( ctx );
915 break;
916
917 case GL_FOG:
918 MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
919 if (ctx->Fog.Enabled)
920 mmesa->setup.maccess |= MA_fogen_enable;
921 else
922 mmesa->setup.maccess &= ~MA_fogen_enable;
923
924 mgaChooseVertexState( ctx );
925 break;
926 case GL_CULL_FACE:
927 mgaDDCullFaceFrontFace( ctx, 0 );
928 break;
929 case GL_TEXTURE_1D:
930 case GL_TEXTURE_2D:
931 case GL_TEXTURE_3D:
932 break;
933 case GL_POLYGON_STIPPLE:
934 if (mmesa->haveHwStipple && mmesa->raster_primitive == GL_TRIANGLES) {
935 FLUSH_BATCH(mmesa);
936 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
937 mmesa->setup.dwgctl &= ~(0xf<<20);
938 if (state)
939 mmesa->setup.dwgctl |= mmesa->poly_stipple;
940 }
941 break;
942 case GL_COLOR_LOGIC_OP:
943 FLUSH_BATCH( mmesa );
944 #if !defined(ACCEL_ROP)
945 FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
946 (state && ctx->Color.LogicOp != GL_COPY));
947 #endif
948 break;
949 case GL_STENCIL_TEST:
950 FLUSH_BATCH( mmesa );
951 if (mmesa->hw_stencil) {
952 mmesa->hw.stencil_enable = ( state ) ? ~0 : 0;
953 }
954 else {
955 FALLBACK( ctx, MGA_FALLBACK_STENCIL, state );
956 }
957 default:
958 break;
959 }
960 }
961
962
963 /* =============================================================
964 */
965
966 static void mgaDDPrintDirty( const char *msg, GLuint state )
967 {
968 fprintf(stderr, "%s (0x%03x): %s%s%s%s%s%s%s\n",
969 msg,
970 (unsigned int) state,
971 (state & MGA_WAIT_AGE) ? "wait-age " : "",
972 (state & MGA_UPLOAD_TEX0IMAGE) ? "upload-tex0-img " : "",
973 (state & MGA_UPLOAD_TEX1IMAGE) ? "upload-tex1-img " : "",
974 (state & MGA_UPLOAD_CONTEXT) ? "upload-ctx " : "",
975 (state & MGA_UPLOAD_TEX0) ? "upload-tex0 " : "",
976 (state & MGA_UPLOAD_TEX1) ? "upload-tex1 " : "",
977 (state & MGA_UPLOAD_PIPE) ? "upload-pipe " : ""
978 );
979 }
980
981 /* Push the state into the sarea and/or texture memory.
982 */
983 void mgaEmitHwStateLocked( mgaContextPtr mmesa )
984 {
985 MGASAREAPrivPtr sarea = mmesa->sarea;
986 GLcontext * ctx = mmesa->glCtx;
987
988 if (MGA_DEBUG & DEBUG_VERBOSE_MSG)
989 mgaDDPrintDirty( __FUNCTION__, mmesa->dirty );
990
991 if (mmesa->dirty & MGA_UPLOAD_CONTEXT) {
992 mmesa->setup.wflag = _CULL_DISABLE;
993 if (mmesa->raster_primitive == GL_TRIANGLES) {
994 if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT &&
995 ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) {
996 mmesa->setup.wflag = mmesa->hw.cull_dualtex;
997 }
998 else {
999 mmesa->setup.wflag = mmesa->hw.cull;
1000 }
1001 }
1002
1003 mmesa->setup.stencil = mmesa->hw.stencil
1004 & mmesa->hw.stencil_enable;
1005 mmesa->setup.stencilctl = mmesa->hw.stencilctl
1006 & mmesa->hw.stencil_enable;
1007
1008 /* If depth testing is not enabled, then use the no Z-compare / no
1009 * Z-write mode. Otherwise, use whatever is set in hw.zmode.
1010 */
1011 mmesa->setup.dwgctl &= (DC_zmode_MASK & DC_atype_MASK);
1012 mmesa->setup.dwgctl |= (ctx->Depth.Test)
1013 ? mmesa->hw.zmode : (DC_zmode_nozcmp | DC_atype_i);
1014
1015 #if defined(ACCEL_ROP)
1016 mmesa->setup.dwgctl &= DC_bop_MASK;
1017 mmesa->setup.dwgctl |= (ctx->Color.ColorLogicOpEnabled)
1018 ? mmesa->hw.rop : mgarop_NoBLK[ GL_COPY & 0x0f ];
1019 #endif
1020
1021 mmesa->setup.alphactrl &= AC_src_MASK & AC_dst_MASK & AC_atmode_MASK
1022 & AC_atref_MASK & AC_alphasel_MASK;
1023 mmesa->setup.alphactrl |=
1024 ((mmesa->hw.alpha_func & mmesa->hw.alpha_func_enable)
1025 | ((mmesa->hw.blend_func & mmesa->hw.blend_func_enable)
1026 | ((AC_src_one | AC_dst_zero) & ~mmesa->hw.blend_func_enable))
1027 | mmesa->hw.alpha_sel
1028 | (AC_amode_alpha_channel
1029 | AC_astipple_disable
1030 | AC_aten_disable
1031 | AC_atmode_noacmp));
1032
1033 memcpy( &sarea->ContextState, &mmesa->setup, sizeof(mmesa->setup));
1034 }
1035
1036 if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) {
1037 mmesa->CurrentTexObj[0]->setup.texctl2 &= ~TMC_specen_enable;
1038 mmesa->CurrentTexObj[0]->setup.texctl2 |= mmesa->hw.specen;
1039
1040 memcpy(&sarea->TexState[0],
1041 &mmesa->CurrentTexObj[0]->setup,
1042 sizeof(sarea->TexState[0]));
1043 }
1044
1045 if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) {
1046 mmesa->CurrentTexObj[1]->setup.texctl2 &= ~TMC_specen_enable;
1047 mmesa->CurrentTexObj[1]->setup.texctl2 |= mmesa->hw.specen;
1048
1049 memcpy(&sarea->TexState[1],
1050 &mmesa->CurrentTexObj[1]->setup,
1051 sizeof(sarea->TexState[1]));
1052 }
1053
1054 if ( (sarea->TexState[0].texctl2 & TMC_borderen_MASK) !=
1055 (sarea->TexState[1].texctl2 & TMC_borderen_MASK) ) {
1056 const int borderen = sarea->TexState[1].texctl2 & ~TMC_borderen_MASK;
1057
1058 memcpy( &sarea->TexState[1], &sarea->TexState[0],
1059 sizeof(sarea->TexState[0]) );
1060 sarea->TexState[1].texctl2 |= borderen;
1061 mmesa->dirty |= MGA_UPLOAD_TEX1|MGA_UPLOAD_TEX0;
1062 }
1063
1064 if (mmesa->dirty & MGA_UPLOAD_PIPE) {
1065 /* mmesa->sarea->wacceptseq = mmesa->hw_primitive; */
1066 mmesa->sarea->WarpPipe = mmesa->vertex_format;
1067 mmesa->sarea->vertsize = mmesa->vertex_size;
1068 }
1069
1070 mmesa->sarea->dirty |= mmesa->dirty;
1071 mmesa->dirty &= MGA_UPLOAD_CLIPRECTS;
1072
1073 /* This is a bit of a hack but seems to be the best place to ensure
1074 * that separate specular is disabled when not needed.
1075 */
1076 if (ctx->Texture._EnabledUnits == 0 ||
1077 !ctx->Light.Enabled ||
1078 ctx->Light.Model.ColorControl == GL_SINGLE_COLOR) {
1079 sarea->TexState[0].texctl2 &= ~TMC_specen_enable;
1080 sarea->TexState[1].texctl2 &= ~TMC_specen_enable;
1081 }
1082 }
1083
1084
1085 /* =============================================================
1086 */
1087
1088
1089 static void mgaDDValidateState( GLcontext *ctx )
1090 {
1091 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
1092 int new_state = mmesa->NewGLState;
1093
1094
1095 FLUSH_BATCH( mmesa );
1096
1097 if (mmesa->NewGLState & _MGA_NEW_RASTERSETUP) {
1098 mgaChooseVertexState( ctx );
1099 }
1100
1101 if (mmesa->NewGLState & _MGA_NEW_RENDERSTATE) {
1102 mgaChooseRenderState( ctx );
1103 }
1104
1105 if (new_state & _NEW_TEXTURE) {
1106 mgaUpdateTextureState(ctx);
1107 }
1108
1109 mmesa->NewGLState = 0;
1110 }
1111
1112
1113 static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state )
1114 {
1115 _swrast_InvalidateState( ctx, new_state );
1116 _swsetup_InvalidateState( ctx, new_state );
1117 _ac_InvalidateState( ctx, new_state );
1118 _tnl_InvalidateState( ctx, new_state );
1119 MGA_CONTEXT(ctx)->NewGLState |= new_state;
1120 }
1121
1122
1123 static void mgaRunPipeline( GLcontext *ctx )
1124 {
1125 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
1126
1127 if (mmesa->NewGLState) {
1128 mgaDDValidateState( ctx );
1129 }
1130
1131 if (mmesa->dirty) {
1132 mgaEmitHwStateLocked( mmesa );
1133 }
1134
1135 _tnl_run_pipeline( ctx );
1136 }
1137
1138
1139 void mgaInitState( mgaContextPtr mmesa )
1140 {
1141 mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
1142 GLcontext *ctx = mmesa->glCtx;
1143
1144 if (ctx->Visual.doubleBufferMode) {
1145 /* use back buffer by default */
1146 mmesa->draw_buffer = MGA_BACK;
1147 mmesa->drawOffset = mmesa->mgaScreen->backOffset;
1148 mmesa->readOffset = mmesa->mgaScreen->backOffset;
1149 mmesa->setup.dstorg = mgaScreen->backOffset;
1150 } else {
1151 /* use front buffer by default */
1152 mmesa->draw_buffer = MGA_FRONT;
1153 mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
1154 mmesa->readOffset = mmesa->mgaScreen->frontOffset;
1155 mmesa->setup.dstorg = mgaScreen->frontOffset;
1156 }
1157
1158 mmesa->setup.maccess = (MA_memreset_disable |
1159 MA_fogen_disable |
1160 MA_tlutload_disable |
1161 MA_nodither_disable |
1162 MA_dit555_disable);
1163
1164 switch (mmesa->mgaScreen->cpp) {
1165 case 2:
1166 mmesa->setup.maccess |= MA_pwidth_16;
1167 break;
1168 case 4:
1169 mmesa->setup.maccess |= MA_pwidth_32;
1170 break;
1171 default:
1172 fprintf( stderr, "Error: unknown cpp %d, exiting...\n",
1173 mmesa->mgaScreen->cpp );
1174 exit( 1 );
1175 }
1176
1177 switch (mmesa->glCtx->Visual.depthBits) {
1178 case 16:
1179 mmesa->setup.maccess |= MA_zwidth_16;
1180 break;
1181 case 24:
1182 mmesa->setup.maccess |= MA_zwidth_24;
1183 break;
1184 case 32:
1185 mmesa->setup.maccess |= MA_zwidth_32;
1186 break;
1187 }
1188
1189 mmesa->hw.zmode = DC_zmode_zlt | DC_atype_zi;
1190 mmesa->hw.stencil = (0x0ff << S_smsk_SHIFT) | (0x0ff << S_swtmsk_SHIFT);
1191 mmesa->hw.stencilctl = SC_smode_salways | SC_sfailop_keep
1192 | SC_szfailop_keep | SC_szpassop_keep;
1193 mmesa->hw.stencil_enable = 0;
1194 mmesa->hw.cull = _CULL_NEGATIVE;
1195 mmesa->hw.cull_dualtex = _CULL_POSITIVE;
1196 mmesa->hw.specen = 0;
1197
1198 mmesa->setup.dwgctl = (DC_opcod_trap |
1199 DC_linear_xy |
1200 DC_solid_disable |
1201 DC_arzero_disable |
1202 DC_sgnzero_disable |
1203 DC_shftzero_enable |
1204 (0xC << DC_bop_SHIFT) |
1205 (0x0 << DC_trans_SHIFT) |
1206 DC_bltmod_bmonolef |
1207 DC_pattern_disable |
1208 DC_transc_disable |
1209 DC_clipdis_disable);
1210
1211
1212 mmesa->setup.plnwt = ~0;
1213 mmesa->setup.alphactrl = ( AC_src_one |
1214 AC_dst_zero |
1215 AC_amode_FCOL |
1216 AC_astipple_disable |
1217 AC_aten_disable |
1218 AC_atmode_noacmp |
1219 AC_alphasel_fromtex );
1220
1221 mmesa->setup.fogcolor = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F),
1222 (GLubyte)(ctx->Fog.Color[1]*255.0F),
1223 (GLubyte)(ctx->Fog.Color[2]*255.0F));
1224
1225 mmesa->setup.wflag = 0;
1226 mmesa->setup.tdualstage0 = 0;
1227 mmesa->setup.tdualstage1 = 0;
1228 mmesa->setup.fcol = 0;
1229 mmesa->dirty |= MGA_UPLOAD_CONTEXT;
1230 }
1231
1232
1233 void mgaDDInitStateFuncs( GLcontext *ctx )
1234 {
1235 ctx->Driver.UpdateState = mgaDDInvalidateState;
1236 ctx->Driver.Enable = mgaDDEnable;
1237 ctx->Driver.LightModelfv = mgaDDLightModelfv;
1238 ctx->Driver.AlphaFunc = mgaDDAlphaFunc;
1239 ctx->Driver.BlendEquation = mgaDDBlendEquation;
1240 ctx->Driver.BlendFunc = mgaDDBlendFunc;
1241 ctx->Driver.BlendFuncSeparate = mgaDDBlendFuncSeparate;
1242 ctx->Driver.DepthFunc = mgaDDDepthFunc;
1243 ctx->Driver.DepthMask = mgaDDDepthMask;
1244 ctx->Driver.Fogfv = mgaDDFogfv;
1245 ctx->Driver.Scissor = mgaDDScissor;
1246 ctx->Driver.ShadeModel = mgaDDShadeModel;
1247 ctx->Driver.CullFace = mgaDDCullFaceFrontFace;
1248 ctx->Driver.FrontFace = mgaDDCullFaceFrontFace;
1249 ctx->Driver.ColorMask = mgaDDColorMask;
1250
1251 ctx->Driver.DrawBuffer = mgaDDDrawBuffer;
1252 ctx->Driver.ReadBuffer = mgaDDReadBuffer;
1253 ctx->Driver.ClearColor = mgaDDClearColor;
1254 ctx->Driver.ClearDepth = mgaDDClearDepth;
1255 ctx->Driver.LogicOpcode = mgaDDLogicOp;
1256
1257 ctx->Driver.PolygonStipple = mgaDDPolygonStipple;
1258
1259 ctx->Driver.StencilFunc = mgaDDStencilFunc;
1260 ctx->Driver.StencilMask = mgaDDStencilMask;
1261 ctx->Driver.StencilOp = mgaDDStencilOp;
1262
1263 ctx->Driver.DepthRange = mgaDepthRange;
1264 ctx->Driver.Viewport = mgaViewport;
1265 ctx->Driver.RenderMode = mgaRenderMode;
1266
1267 ctx->Driver.ClearIndex = 0;
1268 ctx->Driver.IndexMask = 0;
1269
1270 /* Swrast hooks for imaging extensions:
1271 */
1272 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1273 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1274 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1275 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1276
1277 TNL_CONTEXT(ctx)->Driver.RunPipeline = mgaRunPipeline;
1278 }