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