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