Replace ctx->Driver.StencilOp/Func/Mask() functions with
[mesa.git] / src / mesa / drivers / dri / r128 / r128_state.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.c,v 1.11 2002/10/30 12:51:39 alanh Exp $ */
2 /**************************************************************************
3
4 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
5 Cedar Park, Texas.
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
17 Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Gareth Hughes <gareth@valinux.com>
32 * Kevin E. Martin <martin@valinux.com>
33 * Keith Whitwell <keith@tungstengraphics.com>
34 *
35 */
36
37 #include "r128_context.h"
38 #include "r128_state.h"
39 #include "r128_ioctl.h"
40 #include "r128_tris.h"
41 #include "r128_tex.h"
42
43 #include "context.h"
44 #include "buffers.h"
45 #include "enums.h"
46 #include "colormac.h"
47 #include "swrast/swrast.h"
48 #include "array_cache/acache.h"
49 #include "tnl/tnl.h"
50 #include "swrast_setup/swrast_setup.h"
51
52 #include "tnl/t_pipeline.h"
53
54 #include "drirenderbuffer.h"
55
56
57 /* =============================================================
58 * Alpha blending
59 */
60
61
62 /**
63 * Calculate the hardware blend factor setting. This same function is used
64 * for source and destination of both alpha and RGB.
65 *
66 * \returns
67 * The hardware register value for the specified blend factor. This value
68 * will need to be shifted into the correct position for either source or
69 * destination factor.
70 *
71 * \todo
72 * Since the two cases where source and destination are handled differently
73 * are essentially error cases, they should never happen. Determine if these
74 * cases can be removed.
75 */
76 static int blend_factor( r128ContextPtr rmesa, GLenum factor, GLboolean is_src )
77 {
78 int func;
79
80 switch ( factor ) {
81 case GL_ZERO:
82 func = R128_ALPHA_BLEND_ZERO;
83 break;
84 case GL_ONE:
85 func = R128_ALPHA_BLEND_ONE;
86 break;
87
88 case GL_SRC_COLOR:
89 func = R128_ALPHA_BLEND_SRCCOLOR;
90 break;
91 case GL_ONE_MINUS_SRC_COLOR:
92 func = R128_ALPHA_BLEND_INVSRCCOLOR;
93 break;
94 case GL_SRC_ALPHA:
95 func = R128_ALPHA_BLEND_SRCALPHA;
96 break;
97 case GL_ONE_MINUS_SRC_ALPHA:
98 func = R128_ALPHA_BLEND_INVSRCALPHA;
99 break;
100 case GL_SRC_ALPHA_SATURATE:
101 func = (is_src) ? R128_ALPHA_BLEND_SAT : R128_ALPHA_BLEND_ZERO;
102 break;
103
104 case GL_DST_COLOR:
105 func = R128_ALPHA_BLEND_DSTCOLOR;
106 break;
107 case GL_ONE_MINUS_DST_COLOR:
108 func = R128_ALPHA_BLEND_INVDSTCOLOR;
109 break;
110 case GL_DST_ALPHA:
111 func = R128_ALPHA_BLEND_DSTALPHA;
112 break;
113 case GL_ONE_MINUS_DST_ALPHA:
114 func = R128_ALPHA_BLEND_INVDSTALPHA;
115 break;
116
117 case GL_CONSTANT_COLOR:
118 case GL_ONE_MINUS_CONSTANT_COLOR:
119 case GL_CONSTANT_ALPHA:
120 case GL_ONE_MINUS_CONSTANT_ALPHA:
121 default:
122 FALLBACK( rmesa, R128_FALLBACK_BLEND_FUNC, GL_TRUE );
123 func = (is_src) ? R128_ALPHA_BLEND_ONE : R128_ALPHA_BLEND_ZERO;
124 break;
125 }
126
127 return func;
128 }
129
130
131 static void r128UpdateAlphaMode( GLcontext *ctx )
132 {
133 r128ContextPtr rmesa = R128_CONTEXT(ctx);
134 GLuint a = rmesa->setup.misc_3d_state_cntl_reg;
135 GLuint t = rmesa->setup.tex_cntl_c;
136
137 if ( ctx->Color.AlphaEnabled ) {
138 GLubyte ref;
139
140 CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
141
142 a &= ~(R128_ALPHA_TEST_MASK | R128_REF_ALPHA_MASK);
143
144 switch ( ctx->Color.AlphaFunc ) {
145 case GL_NEVER:
146 a |= R128_ALPHA_TEST_NEVER;
147 break;
148 case GL_LESS:
149 a |= R128_ALPHA_TEST_LESS;
150 break;
151 case GL_LEQUAL:
152 a |= R128_ALPHA_TEST_LESSEQUAL;
153 break;
154 case GL_EQUAL:
155 a |= R128_ALPHA_TEST_EQUAL;
156 break;
157 case GL_GEQUAL:
158 a |= R128_ALPHA_TEST_GREATEREQUAL;
159 break;
160 case GL_GREATER:
161 a |= R128_ALPHA_TEST_GREATER;
162 break;
163 case GL_NOTEQUAL:
164 a |= R128_ALPHA_TEST_NEQUAL;
165 break;
166 case GL_ALWAYS:
167 a |= R128_ALPHA_TEST_ALWAYS;
168 break;
169 }
170
171 a |= ref & R128_REF_ALPHA_MASK;
172 t |= R128_ALPHA_TEST_ENABLE;
173 } else {
174 t &= ~R128_ALPHA_TEST_ENABLE;
175 }
176
177 FALLBACK( rmesa, R128_FALLBACK_BLEND_FUNC, GL_FALSE );
178
179 if ( ctx->Color.BlendEnabled ) {
180 a &= ~((R128_ALPHA_BLEND_MASK << R128_ALPHA_BLEND_SRC_SHIFT) |
181 (R128_ALPHA_BLEND_MASK << R128_ALPHA_BLEND_DST_SHIFT)
182 | R128_ALPHA_COMB_FCN_MASK);
183
184 a |= blend_factor( rmesa, ctx->Color.BlendSrcRGB, GL_TRUE )
185 << R128_ALPHA_BLEND_SRC_SHIFT;
186 a |= blend_factor( rmesa, ctx->Color.BlendDstRGB, GL_FALSE )
187 << R128_ALPHA_BLEND_DST_SHIFT;
188
189 switch (ctx->Color.BlendEquationRGB) {
190 case GL_FUNC_ADD:
191 a |= R128_ALPHA_COMB_ADD_CLAMP;
192 break;
193 case GL_FUNC_SUBTRACT:
194 a |= R128_ALPHA_COMB_SUB_SRC_DST_CLAMP;
195 break;
196 default:
197 FALLBACK( rmesa, R128_FALLBACK_BLEND_EQ, GL_TRUE );
198 }
199
200 t |= R128_ALPHA_ENABLE;
201 } else {
202 t &= ~R128_ALPHA_ENABLE;
203 }
204
205 if ( rmesa->setup.misc_3d_state_cntl_reg != a ) {
206 rmesa->setup.misc_3d_state_cntl_reg = a;
207 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
208 }
209 if ( rmesa->setup.tex_cntl_c != t ) {
210 rmesa->setup.tex_cntl_c = t;
211 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
212 }
213 }
214
215 static void r128DDAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
216 {
217 r128ContextPtr rmesa = R128_CONTEXT(ctx);
218
219 FLUSH_BATCH( rmesa );
220 rmesa->new_state |= R128_NEW_ALPHA;
221 }
222
223 static void r128DDBlendEquationSeparate( GLcontext *ctx,
224 GLenum modeRGB, GLenum modeA )
225 {
226 r128ContextPtr rmesa = R128_CONTEXT(ctx);
227
228 assert( modeRGB == modeA );
229 FLUSH_BATCH( rmesa );
230
231 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
232 * manner.
233 */
234 FALLBACK( R128_CONTEXT(ctx), R128_FALLBACK_LOGICOP,
235 (ctx->Color.ColorLogicOpEnabled &&
236 ctx->Color.LogicOp != GL_COPY));
237
238 /* Can only do blend addition, not min, max, subtract, etc. */
239 FALLBACK( R128_CONTEXT(ctx), R128_FALLBACK_BLEND_EQ,
240 (modeRGB != GL_FUNC_ADD) && (modeRGB != GL_FUNC_SUBTRACT));
241
242 rmesa->new_state |= R128_NEW_ALPHA;
243 }
244
245 static void r128DDBlendFuncSeparate( GLcontext *ctx,
246 GLenum sfactorRGB, GLenum dfactorRGB,
247 GLenum sfactorA, GLenum dfactorA )
248 {
249 r128ContextPtr rmesa = R128_CONTEXT(ctx);
250
251 FLUSH_BATCH( rmesa );
252 rmesa->new_state |= R128_NEW_ALPHA;
253 }
254
255
256 /* =============================================================
257 * Depth testing
258 */
259
260 static void r128UpdateZMode( GLcontext *ctx )
261 {
262 r128ContextPtr rmesa = R128_CONTEXT(ctx);
263 GLuint z = rmesa->setup.z_sten_cntl_c;
264 GLuint t = rmesa->setup.tex_cntl_c;
265
266 if ( ctx->Depth.Test ) {
267 z &= ~R128_Z_TEST_MASK;
268
269 switch ( ctx->Depth.Func ) {
270 case GL_NEVER:
271 z |= R128_Z_TEST_NEVER;
272 break;
273 case GL_ALWAYS:
274 z |= R128_Z_TEST_ALWAYS;
275 break;
276 case GL_LESS:
277 z |= R128_Z_TEST_LESS;
278 break;
279 case GL_LEQUAL:
280 z |= R128_Z_TEST_LESSEQUAL;
281 break;
282 case GL_EQUAL:
283 z |= R128_Z_TEST_EQUAL;
284 break;
285 case GL_GEQUAL:
286 z |= R128_Z_TEST_GREATEREQUAL;
287 break;
288 case GL_GREATER:
289 z |= R128_Z_TEST_GREATER;
290 break;
291 case GL_NOTEQUAL:
292 z |= R128_Z_TEST_NEQUAL;
293 break;
294 }
295
296 t |= R128_Z_ENABLE;
297 } else {
298 t &= ~R128_Z_ENABLE;
299 }
300
301 if ( ctx->Depth.Mask ) {
302 t |= R128_Z_WRITE_ENABLE;
303 } else {
304 t &= ~R128_Z_WRITE_ENABLE;
305 }
306
307 if ( rmesa->setup.z_sten_cntl_c != z ) {
308 rmesa->setup.z_sten_cntl_c = z;
309 rmesa->dirty |= R128_UPLOAD_CONTEXT;
310 }
311 if ( rmesa->setup.tex_cntl_c != t ) {
312 rmesa->setup.tex_cntl_c = t;
313 rmesa->dirty |= R128_UPLOAD_CONTEXT;
314 }
315 }
316
317 static void r128DDDepthFunc( GLcontext *ctx, GLenum func )
318 {
319 r128ContextPtr rmesa = R128_CONTEXT(ctx);
320
321 FLUSH_BATCH( rmesa );
322 rmesa->new_state |= R128_NEW_DEPTH;
323 }
324
325 static void r128DDDepthMask( GLcontext *ctx, GLboolean flag )
326 {
327 r128ContextPtr rmesa = R128_CONTEXT(ctx);
328
329 FLUSH_BATCH( rmesa );
330 rmesa->new_state |= R128_NEW_DEPTH;
331 }
332
333 static void r128DDClearDepth( GLcontext *ctx, GLclampd d )
334 {
335 r128ContextPtr rmesa = R128_CONTEXT(ctx);
336
337 switch ( rmesa->setup.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK ) {
338 case R128_Z_PIX_WIDTH_16:
339 rmesa->ClearDepth = d * 0x0000ffff;
340 break;
341 case R128_Z_PIX_WIDTH_24:
342 rmesa->ClearDepth = d * 0x00ffffff;
343 break;
344 case R128_Z_PIX_WIDTH_32:
345 rmesa->ClearDepth = d * 0xffffffff;
346 break;
347 }
348 }
349
350
351 /* =============================================================
352 * Fog
353 */
354
355 static void r128UpdateFogAttrib( GLcontext *ctx )
356 {
357 r128ContextPtr rmesa = R128_CONTEXT(ctx);
358 GLuint t = rmesa->setup.tex_cntl_c;
359 GLubyte c[4];
360 GLuint col;
361
362 if ( ctx->Fog.Enabled ) {
363 t |= R128_FOG_ENABLE;
364 } else {
365 t &= ~R128_FOG_ENABLE;
366 }
367
368 c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] );
369 c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] );
370 c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] );
371
372 col = r128PackColor( 4, c[0], c[1], c[2], 0 );
373
374 if ( rmesa->setup.fog_color_c != col ) {
375 rmesa->setup.fog_color_c = col;
376 rmesa->dirty |= R128_UPLOAD_CONTEXT;
377 }
378 if ( rmesa->setup.tex_cntl_c != t ) {
379 rmesa->setup.tex_cntl_c = t;
380 rmesa->dirty |= R128_UPLOAD_CONTEXT;
381 }
382 }
383
384 static void r128DDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
385 {
386 r128ContextPtr rmesa = R128_CONTEXT(ctx);
387
388 FLUSH_BATCH( rmesa );
389 rmesa->new_state |= R128_NEW_FOG;
390 }
391
392
393 /* =============================================================
394 * Clipping
395 */
396
397 static void r128UpdateClipping( GLcontext *ctx )
398 {
399 r128ContextPtr rmesa = R128_CONTEXT(ctx);
400
401 if ( rmesa->driDrawable ) {
402 __DRIdrawablePrivate *drawable = rmesa->driDrawable;
403 int x1 = 0;
404 int y1 = 0;
405 int x2 = drawable->w - 1;
406 int y2 = drawable->h - 1;
407
408 if ( ctx->Scissor.Enabled ) {
409 if ( ctx->Scissor.X > x1 ) {
410 x1 = ctx->Scissor.X;
411 }
412 if ( drawable->h - ctx->Scissor.Y - ctx->Scissor.Height > y1 ) {
413 y1 = drawable->h - ctx->Scissor.Y - ctx->Scissor.Height;
414 }
415 if ( ctx->Scissor.X + ctx->Scissor.Width - 1 < x2 ) {
416 x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
417 }
418 if ( drawable->h - ctx->Scissor.Y - 1 < y2 ) {
419 y2 = drawable->h - ctx->Scissor.Y - 1;
420 }
421 }
422
423 x1 += drawable->x;
424 y1 += drawable->y;
425 x2 += drawable->x;
426 y2 += drawable->y;
427
428 rmesa->setup.sc_top_left_c = ((y1 << 16) | x1);
429 rmesa->setup.sc_bottom_right_c = ((y2 << 16) | x2);
430
431 rmesa->dirty |= R128_UPLOAD_CONTEXT;
432 }
433 }
434
435 static void r128DDScissor( GLcontext *ctx,
436 GLint x, GLint y, GLsizei w, GLsizei h )
437 {
438 r128ContextPtr rmesa = R128_CONTEXT(ctx);
439
440 FLUSH_BATCH( rmesa );
441 rmesa->new_state |= R128_NEW_CLIP;
442 }
443
444
445 /* =============================================================
446 * Culling
447 */
448
449 static void r128UpdateCull( GLcontext *ctx )
450 {
451 r128ContextPtr rmesa = R128_CONTEXT(ctx);
452 GLuint f = rmesa->setup.pm4_vc_fpu_setup;
453
454 f &= ~R128_FRONT_DIR_MASK;
455
456 switch ( ctx->Polygon.FrontFace ) {
457 case GL_CW:
458 f |= R128_FRONT_DIR_CW;
459 break;
460 case GL_CCW:
461 f |= R128_FRONT_DIR_CCW;
462 break;
463 }
464
465 f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID;
466
467 if ( ctx->Polygon.CullFlag ) {
468 switch ( ctx->Polygon.CullFaceMode ) {
469 case GL_FRONT:
470 f &= ~R128_FRONTFACE_SOLID;
471 break;
472 case GL_BACK:
473 f &= ~R128_BACKFACE_SOLID;
474 break;
475 case GL_FRONT_AND_BACK:
476 f &= ~(R128_BACKFACE_SOLID |
477 R128_FRONTFACE_SOLID);
478 break;
479 }
480 }
481
482 if ( 1 || rmesa->setup.pm4_vc_fpu_setup != f ) {
483 rmesa->setup.pm4_vc_fpu_setup = f;
484 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_SETUP;
485 }
486 }
487
488 static void r128DDCullFace( GLcontext *ctx, GLenum mode )
489 {
490 r128ContextPtr rmesa = R128_CONTEXT(ctx);
491
492 FLUSH_BATCH( rmesa );
493 rmesa->new_state |= R128_NEW_CULL;
494 }
495
496 static void r128DDFrontFace( GLcontext *ctx, GLenum mode )
497 {
498 r128ContextPtr rmesa = R128_CONTEXT(ctx);
499
500 FLUSH_BATCH( rmesa );
501 rmesa->new_state |= R128_NEW_CULL;
502 }
503
504
505 /* =============================================================
506 * Masks
507 */
508
509 static void r128UpdateMasks( GLcontext *ctx )
510 {
511 r128ContextPtr rmesa = R128_CONTEXT(ctx);
512
513 GLuint mask = r128PackColor( rmesa->r128Screen->cpp,
514 ctx->Color.ColorMask[RCOMP],
515 ctx->Color.ColorMask[GCOMP],
516 ctx->Color.ColorMask[BCOMP],
517 ctx->Color.ColorMask[ACOMP] );
518
519 if ( rmesa->setup.plane_3d_mask_c != mask ) {
520 rmesa->setup.plane_3d_mask_c = mask;
521 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
522 }
523 }
524
525 static void r128DDColorMask( GLcontext *ctx,
526 GLboolean r, GLboolean g,
527 GLboolean b, GLboolean a )
528 {
529 r128ContextPtr rmesa = R128_CONTEXT(ctx);
530
531 FLUSH_BATCH( rmesa );
532 rmesa->new_state |= R128_NEW_MASKS;
533 }
534
535
536 /* =============================================================
537 * Rendering attributes
538 *
539 * We really don't want to recalculate all this every time we bind a
540 * texture. These things shouldn't change all that often, so it makes
541 * sense to break them out of the core texture state update routines.
542 */
543
544 static void updateSpecularLighting( GLcontext *ctx )
545 {
546 r128ContextPtr rmesa = R128_CONTEXT(ctx);
547 GLuint t = rmesa->setup.tex_cntl_c;
548
549 if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
550 ctx->Light.Enabled) {
551 /* XXX separate specular color just doesn't seem to work as it should.
552 * For now, we fall back to s/w rendering whenever separate specular
553 * is enabled.
554 */
555 #if 0
556 if (ctx->Light.ShadeModel == GL_FLAT) {
557 /* R128 can't do flat-shaded separate specular */
558 t &= ~R128_SPEC_LIGHT_ENABLE;
559 FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_TRUE );
560 /*printf("%s fallback sep spec\n", __FUNCTION__);*/
561 }
562 else {
563 t |= R128_SPEC_LIGHT_ENABLE;
564 FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_FALSE );
565 /*printf("%s enable sep spec\n", __FUNCTION__);*/
566 }
567 #else
568 t &= ~R128_SPEC_LIGHT_ENABLE;
569 FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_TRUE );
570 /*printf("%s fallback sep spec\n", __FUNCTION__);*/
571 #endif
572 }
573 else {
574 t &= ~R128_SPEC_LIGHT_ENABLE;
575 FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_FALSE );
576 /*printf("%s disable sep spec\n", __FUNCTION__);*/
577 }
578
579 if ( rmesa->setup.tex_cntl_c != t ) {
580 rmesa->setup.tex_cntl_c = t;
581 rmesa->dirty |= R128_UPLOAD_CONTEXT;
582 rmesa->dirty |= R128_UPLOAD_SETUP;
583 rmesa->new_state |= R128_NEW_CONTEXT;
584 }
585 }
586
587
588 static void r128DDLightModelfv( GLcontext *ctx, GLenum pname,
589 const GLfloat *param )
590 {
591 r128ContextPtr rmesa = R128_CONTEXT(ctx);
592
593 if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) {
594 FLUSH_BATCH( rmesa );
595 updateSpecularLighting(ctx);
596 }
597 }
598
599 static void r128DDShadeModel( GLcontext *ctx, GLenum mode )
600 {
601 r128ContextPtr rmesa = R128_CONTEXT(ctx);
602 GLuint s = rmesa->setup.pm4_vc_fpu_setup;
603
604 s &= ~R128_FPU_COLOR_MASK;
605
606 switch ( mode ) {
607 case GL_FLAT:
608 s |= R128_FPU_COLOR_FLAT;
609 break;
610 case GL_SMOOTH:
611 s |= R128_FPU_COLOR_GOURAUD;
612 break;
613 default:
614 return;
615 }
616
617 updateSpecularLighting(ctx);
618
619 if ( rmesa->setup.pm4_vc_fpu_setup != s ) {
620 FLUSH_BATCH( rmesa );
621 rmesa->setup.pm4_vc_fpu_setup = s;
622
623 rmesa->new_state |= R128_NEW_CONTEXT;
624 rmesa->dirty |= R128_UPLOAD_SETUP;
625 }
626 }
627
628
629 /* =============================================================
630 * Window position
631 */
632
633 static void r128UpdateWindow( GLcontext *ctx )
634 {
635 r128ContextPtr rmesa = R128_CONTEXT(ctx);
636 int x = rmesa->driDrawable->x;
637 int y = rmesa->driDrawable->y;
638 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0];
639 driRenderbuffer *drb = (driRenderbuffer *) rb;
640
641 rmesa->setup.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) |
642 (x << R128_WINDOW_X_SHIFT));
643
644 rmesa->setup.dst_pitch_offset_c = (((drb->flippedPitch/8) << 21) |
645 (drb->flippedOffset >> 5));
646
647
648 rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_WINDOW;
649 }
650
651
652 /* =============================================================
653 * Viewport
654 */
655
656 static void r128CalcViewport( GLcontext *ctx )
657 {
658 r128ContextPtr rmesa = R128_CONTEXT(ctx);
659 const GLfloat *v = ctx->Viewport._WindowMap.m;
660 GLfloat *m = rmesa->hw_viewport;
661
662 /* See also r128_translate_vertex.
663 */
664 m[MAT_SX] = v[MAT_SX];
665 m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
666 m[MAT_SY] = - v[MAT_SY];
667 m[MAT_TY] = - v[MAT_TY] + rmesa->driDrawable->h + SUBPIXEL_Y;
668 m[MAT_SZ] = v[MAT_SZ] * rmesa->depth_scale;
669 m[MAT_TZ] = v[MAT_TZ] * rmesa->depth_scale;
670 }
671
672 static void r128Viewport( GLcontext *ctx,
673 GLint x, GLint y,
674 GLsizei width, GLsizei height )
675 {
676 /* update size of Mesa/software ancillary buffers */
677 _mesa_ResizeBuffersMESA();
678 r128CalcViewport( ctx );
679 }
680
681 static void r128DepthRange( GLcontext *ctx,
682 GLclampd nearval, GLclampd farval )
683 {
684 r128CalcViewport( ctx );
685 }
686
687
688 /* =============================================================
689 * Miscellaneous
690 */
691
692 static void r128DDClearColor( GLcontext *ctx,
693 const GLfloat color[4] )
694 {
695 r128ContextPtr rmesa = R128_CONTEXT(ctx);
696 GLubyte c[4];
697
698 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
699 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
700 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
701 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
702
703 rmesa->ClearColor = r128PackColor( rmesa->r128Screen->cpp,
704 c[0], c[1], c[2], c[3] );
705 }
706
707 static void r128DDLogicOpCode( GLcontext *ctx, GLenum opcode )
708 {
709 r128ContextPtr rmesa = R128_CONTEXT(ctx);
710
711 if ( ctx->Color.ColorLogicOpEnabled ) {
712 FLUSH_BATCH( rmesa );
713
714 FALLBACK( rmesa, R128_FALLBACK_LOGICOP, opcode != GL_COPY );
715 }
716 }
717
718 static void r128DDDrawBuffer( GLcontext *ctx, GLenum mode )
719 {
720 r128ContextPtr rmesa = R128_CONTEXT(ctx);
721
722 FLUSH_BATCH( rmesa );
723
724 /*
725 * _ColorDrawBufferMask is easier to cope with than <mode>.
726 */
727 switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
728 case BUFFER_BIT_FRONT_LEFT:
729 FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_FALSE );
730 break;
731 case BUFFER_BIT_BACK_LEFT:
732 FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_FALSE );
733 break;
734 default:
735 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
736 FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_TRUE );
737 break;
738 }
739
740 rmesa->new_state |= R128_NEW_WINDOW;
741 }
742
743 static void r128DDReadBuffer( GLcontext *ctx, GLenum mode )
744 {
745 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
746 }
747
748
749 /* =============================================================
750 * Polygon stipple
751 */
752
753 static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
754 {
755 r128ContextPtr rmesa = R128_CONTEXT(ctx);
756 GLuint stipple[32], i;
757 drm_r128_stipple_t stippleRec;
758
759 for (i = 0; i < 32; i++) {
760 stipple[31 - i] = ((mask[i*4+0] << 24) |
761 (mask[i*4+1] << 16) |
762 (mask[i*4+2] << 8) |
763 (mask[i*4+3]));
764 }
765
766 FLUSH_BATCH( rmesa );
767 LOCK_HARDWARE( rmesa );
768
769 stippleRec.mask = stipple;
770 drmCommandWrite( rmesa->driFd, DRM_R128_STIPPLE,
771 &stippleRec, sizeof(stippleRec) );
772
773 UNLOCK_HARDWARE( rmesa );
774
775 rmesa->new_state |= R128_NEW_CONTEXT;
776 rmesa->dirty |= R128_UPLOAD_CONTEXT;
777 }
778
779
780 /* =============================================================
781 * Render mode
782 */
783
784 static void r128DDRenderMode( GLcontext *ctx, GLenum mode )
785 {
786 r128ContextPtr rmesa = R128_CONTEXT(ctx);
787 FALLBACK( rmesa, R128_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
788 }
789
790
791
792 /* =============================================================
793 * State enable/disable
794 */
795
796 static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
797 {
798 r128ContextPtr rmesa = R128_CONTEXT(ctx);
799
800 if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
801 fprintf( stderr, "%s( %s = %s )\n",
802 __FUNCTION__, _mesa_lookup_enum_by_nr( cap ),
803 state ? "GL_TRUE" : "GL_FALSE" );
804 }
805
806 switch ( cap ) {
807 case GL_ALPHA_TEST:
808 FLUSH_BATCH( rmesa );
809 rmesa->new_state |= R128_NEW_ALPHA;
810 break;
811
812 case GL_BLEND:
813 FLUSH_BATCH( rmesa );
814 rmesa->new_state |= R128_NEW_ALPHA;
815
816 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
817 */
818 FALLBACK( rmesa, R128_FALLBACK_LOGICOP,
819 (ctx->Color.ColorLogicOpEnabled &&
820 ctx->Color.LogicOp != GL_COPY));
821 break;
822
823 case GL_CULL_FACE:
824 FLUSH_BATCH( rmesa );
825 rmesa->new_state |= R128_NEW_CULL;
826 break;
827
828 case GL_DEPTH_TEST:
829 FLUSH_BATCH( rmesa );
830 rmesa->new_state |= R128_NEW_DEPTH;
831 break;
832
833 case GL_DITHER:
834 do {
835 GLuint t = rmesa->setup.tex_cntl_c;
836 FLUSH_BATCH( rmesa );
837
838 if ( ctx->Color.DitherFlag ) {
839 t |= R128_DITHER_ENABLE;
840 } else {
841 t &= ~R128_DITHER_ENABLE;
842 }
843
844 if ( rmesa->setup.tex_cntl_c != t ) {
845 rmesa->setup.tex_cntl_c = t;
846 rmesa->dirty |= R128_UPLOAD_CONTEXT;
847 }
848 } while (0);
849 break;
850
851 case GL_FOG:
852 FLUSH_BATCH( rmesa );
853 rmesa->new_state |= R128_NEW_FOG;
854 break;
855
856 case GL_COLOR_LOGIC_OP:
857 FLUSH_BATCH( rmesa );
858 FALLBACK( rmesa, R128_FALLBACK_LOGICOP,
859 state && ctx->Color.LogicOp != GL_COPY );
860 break;
861
862 case GL_LIGHTING:
863 updateSpecularLighting(ctx);
864 break;
865
866 case GL_SCISSOR_TEST:
867 FLUSH_BATCH( rmesa );
868 rmesa->scissor = state;
869 rmesa->new_state |= R128_NEW_CLIP;
870 break;
871
872 case GL_STENCIL_TEST:
873 FLUSH_BATCH( rmesa );
874 FALLBACK( rmesa, R128_FALLBACK_STENCIL, state );
875 break;
876
877 case GL_TEXTURE_1D:
878 case GL_TEXTURE_2D:
879 case GL_TEXTURE_3D:
880 FLUSH_BATCH( rmesa );
881 break;
882
883 case GL_POLYGON_STIPPLE:
884 if ( rmesa->render_primitive == GL_TRIANGLES ) {
885 FLUSH_BATCH( rmesa );
886 rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE;
887 if ( state ) {
888 rmesa->setup.dp_gui_master_cntl_c |=
889 R128_GMC_BRUSH_32x32_MONO_FG_LA;
890 } else {
891 rmesa->setup.dp_gui_master_cntl_c |=
892 R128_GMC_BRUSH_SOLID_COLOR;
893 }
894 rmesa->new_state |= R128_NEW_CONTEXT;
895 rmesa->dirty |= R128_UPLOAD_CONTEXT;
896 }
897 break;
898
899 default:
900 return;
901 }
902 }
903
904
905 /* =============================================================
906 * State initialization, management
907 */
908
909 static void r128DDPrintDirty( const char *msg, GLuint state )
910 {
911 fprintf( stderr,
912 "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
913 msg,
914 state,
915 (state & R128_UPLOAD_CORE) ? "core, " : "",
916 (state & R128_UPLOAD_CONTEXT) ? "context, " : "",
917 (state & R128_UPLOAD_SETUP) ? "setup, " : "",
918 (state & R128_UPLOAD_TEX0) ? "tex0, " : "",
919 (state & R128_UPLOAD_TEX1) ? "tex1, " : "",
920 (state & R128_UPLOAD_MASKS) ? "masks, " : "",
921 (state & R128_UPLOAD_WINDOW) ? "window, " : "",
922 (state & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
923 (state & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
924 }
925
926 /*
927 * Load the current context's state into the hardware.
928 *
929 * NOTE: Be VERY careful about ensuring the context state is marked for
930 * upload, the only place it shouldn't be uploaded is when the setup
931 * state has changed in ReducedPrimitiveChange as this comes right after
932 * a state update.
933 *
934 * Blits of any type should always upload the context and masks after
935 * they are done.
936 */
937 void r128EmitHwStateLocked( r128ContextPtr rmesa )
938 {
939 drm_r128_sarea_t *sarea = rmesa->sarea;
940 drm_r128_context_regs_t *regs = &(rmesa->setup);
941 const r128TexObjPtr t0 = rmesa->CurrentTexObj[0];
942 const r128TexObjPtr t1 = rmesa->CurrentTexObj[1];
943
944 if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) {
945 r128DDPrintDirty( "r128EmitHwStateLocked", rmesa->dirty );
946 }
947
948 if ( rmesa->dirty & (R128_UPLOAD_CONTEXT |
949 R128_UPLOAD_SETUP |
950 R128_UPLOAD_MASKS |
951 R128_UPLOAD_WINDOW |
952 R128_UPLOAD_CORE) ) {
953 memcpy( &sarea->context_state, regs, sizeof(sarea->context_state) );
954 }
955
956 if ( (rmesa->dirty & R128_UPLOAD_TEX0) && t0 ) {
957 drm_r128_texture_regs_t *tex = &sarea->tex_state[0];
958
959 tex->tex_cntl = t0->setup.tex_cntl;
960 tex->tex_combine_cntl = rmesa->tex_combine[0];
961 tex->tex_size_pitch = t0->setup.tex_size_pitch;
962 memcpy( &tex->tex_offset[0], &t0->setup.tex_offset[0],
963 sizeof(tex->tex_offset ) );
964 tex->tex_border_color = t0->setup.tex_border_color;
965 }
966
967 if ( (rmesa->dirty & R128_UPLOAD_TEX1) && t1 ) {
968 drm_r128_texture_regs_t *tex = &sarea->tex_state[1];
969
970 tex->tex_cntl = t1->setup.tex_cntl;
971 tex->tex_combine_cntl = rmesa->tex_combine[1];
972 tex->tex_size_pitch = t1->setup.tex_size_pitch;
973 memcpy( &tex->tex_offset[0], &t1->setup.tex_offset[0],
974 sizeof(tex->tex_offset ) );
975 tex->tex_border_color = t1->setup.tex_border_color;
976 }
977
978 sarea->vertsize = rmesa->vertex_size;
979 sarea->vc_format = rmesa->vertex_format;
980
981 /* Turn off the texture cache flushing */
982 rmesa->setup.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
983
984 sarea->dirty |= rmesa->dirty;
985 rmesa->dirty &= R128_UPLOAD_CLIPRECTS;
986 }
987
988 static void r128DDPrintState( const char *msg, GLuint flags )
989 {
990 fprintf( stderr,
991 "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
992 msg,
993 flags,
994 (flags & R128_NEW_CONTEXT) ? "context, " : "",
995 (flags & R128_NEW_ALPHA) ? "alpha, " : "",
996 (flags & R128_NEW_DEPTH) ? "depth, " : "",
997 (flags & R128_NEW_FOG) ? "fog, " : "",
998 (flags & R128_NEW_CLIP) ? "clip, " : "",
999 (flags & R128_NEW_CULL) ? "cull, " : "",
1000 (flags & R128_NEW_MASKS) ? "masks, " : "",
1001 (flags & R128_NEW_WINDOW) ? "window, " : "" );
1002 }
1003
1004 void r128DDUpdateHWState( GLcontext *ctx )
1005 {
1006 r128ContextPtr rmesa = R128_CONTEXT(ctx);
1007 int new_state = rmesa->new_state;
1008
1009 if ( new_state || rmesa->NewGLState & _NEW_TEXTURE )
1010 {
1011 FLUSH_BATCH( rmesa );
1012
1013 rmesa->new_state = 0;
1014
1015 if ( R128_DEBUG & DEBUG_VERBOSE_MSG )
1016 r128DDPrintState( "r128UpdateHwState", new_state );
1017
1018 /* Update the various parts of the context's state.
1019 */
1020 if ( new_state & R128_NEW_ALPHA )
1021 r128UpdateAlphaMode( ctx );
1022
1023 if ( new_state & R128_NEW_DEPTH )
1024 r128UpdateZMode( ctx );
1025
1026 if ( new_state & R128_NEW_FOG )
1027 r128UpdateFogAttrib( ctx );
1028
1029 if ( new_state & R128_NEW_CLIP )
1030 r128UpdateClipping( ctx );
1031
1032 if ( new_state & R128_NEW_CULL )
1033 r128UpdateCull( ctx );
1034
1035 if ( new_state & R128_NEW_MASKS )
1036 r128UpdateMasks( ctx );
1037
1038 if ( new_state & R128_NEW_WINDOW )
1039 r128UpdateWindow( ctx );
1040
1041 if ( rmesa->NewGLState & _NEW_TEXTURE ) {
1042 r128UpdateTextureState( ctx );
1043 }
1044 }
1045 }
1046
1047
1048 static void r128DDInvalidateState( GLcontext *ctx, GLuint new_state )
1049 {
1050 _swrast_InvalidateState( ctx, new_state );
1051 _swsetup_InvalidateState( ctx, new_state );
1052 _ac_InvalidateState( ctx, new_state );
1053 _tnl_InvalidateState( ctx, new_state );
1054 R128_CONTEXT(ctx)->NewGLState |= new_state;
1055 }
1056
1057
1058
1059 /* Initialize the context's hardware state.
1060 */
1061 void r128DDInitState( r128ContextPtr rmesa )
1062 {
1063 int dst_bpp, depth_bpp;
1064
1065 switch ( rmesa->r128Screen->cpp ) {
1066 case 2:
1067 dst_bpp = R128_GMC_DST_16BPP;
1068 break;
1069 case 4:
1070 dst_bpp = R128_GMC_DST_32BPP;
1071 break;
1072 default:
1073 fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" );
1074 exit( -1 );
1075 }
1076
1077 rmesa->ClearColor = 0x00000000;
1078
1079 switch ( rmesa->glCtx->Visual.depthBits ) {
1080 case 16:
1081 rmesa->ClearDepth = 0x0000ffff;
1082 depth_bpp = R128_Z_PIX_WIDTH_16;
1083 rmesa->depth_scale = 1.0 / (GLfloat)0xffff;
1084 break;
1085 case 24:
1086 rmesa->ClearDepth = 0x00ffffff;
1087 depth_bpp = R128_Z_PIX_WIDTH_24;
1088 rmesa->depth_scale = 1.0 / (GLfloat)0xffffff;
1089 break;
1090 default:
1091 fprintf( stderr, "Error: Unsupported depth %d... exiting\n",
1092 rmesa->glCtx->Visual.depthBits );
1093 exit( -1 );
1094 }
1095
1096 rmesa->Fallback = 0;
1097
1098 /* Hardware state:
1099 */
1100 rmesa->setup.dp_gui_master_cntl_c = (R128_GMC_DST_PITCH_OFFSET_CNTL |
1101 R128_GMC_DST_CLIPPING |
1102 R128_GMC_BRUSH_SOLID_COLOR |
1103 dst_bpp |
1104 R128_GMC_SRC_DATATYPE_COLOR |
1105 R128_GMC_BYTE_MSB_TO_LSB |
1106 R128_GMC_CONVERSION_TEMP_6500 |
1107 R128_ROP3_S |
1108 R128_DP_SRC_SOURCE_MEMORY |
1109 R128_GMC_3D_FCN_EN |
1110 R128_GMC_CLR_CMP_CNTL_DIS |
1111 R128_GMC_AUX_CLIP_DIS |
1112 R128_GMC_WR_MSK_DIS);
1113
1114 rmesa->setup.sc_top_left_c = 0x00000000;
1115 rmesa->setup.sc_bottom_right_c = 0x1fff1fff;
1116
1117 rmesa->setup.z_offset_c = rmesa->r128Screen->depthOffset;
1118 rmesa->setup.z_pitch_c = ((rmesa->r128Screen->depthPitch >> 3) |
1119 R128_Z_TILE);
1120
1121 rmesa->setup.z_sten_cntl_c = (depth_bpp |
1122 R128_Z_TEST_LESS |
1123 R128_STENCIL_TEST_ALWAYS |
1124 R128_STENCIL_S_FAIL_KEEP |
1125 R128_STENCIL_ZPASS_KEEP |
1126 R128_STENCIL_ZFAIL_KEEP);
1127
1128 rmesa->setup.tex_cntl_c = (R128_Z_WRITE_ENABLE |
1129 R128_SHADE_ENABLE |
1130 R128_DITHER_ENABLE |
1131 R128_ALPHA_IN_TEX_COMPLETE_A |
1132 R128_LIGHT_DIS |
1133 R128_ALPHA_LIGHT_DIS |
1134 R128_TEX_CACHE_FLUSH |
1135 (0x3f << R128_LOD_BIAS_SHIFT));
1136
1137 rmesa->setup.misc_3d_state_cntl_reg = (R128_MISC_SCALE_3D_TEXMAP_SHADE |
1138 R128_MISC_SCALE_PIX_REPLICATE |
1139 R128_ALPHA_COMB_ADD_CLAMP |
1140 R128_FOG_VERTEX |
1141 (R128_ALPHA_BLEND_ONE << R128_ALPHA_BLEND_SRC_SHIFT) |
1142 (R128_ALPHA_BLEND_ZERO << R128_ALPHA_BLEND_DST_SHIFT) |
1143 R128_ALPHA_TEST_ALWAYS);
1144
1145 rmesa->setup.texture_clr_cmp_clr_c = 0x00000000;
1146 rmesa->setup.texture_clr_cmp_msk_c = 0xffffffff;
1147
1148 rmesa->setup.fog_color_c = 0x00000000;
1149
1150 rmesa->setup.pm4_vc_fpu_setup = (R128_FRONT_DIR_CCW |
1151 R128_BACKFACE_SOLID |
1152 R128_FRONTFACE_SOLID |
1153 R128_FPU_COLOR_GOURAUD |
1154 R128_FPU_SUB_PIX_4BITS |
1155 R128_FPU_MODE_3D |
1156 R128_TRAP_BITS_DISABLE |
1157 R128_XFACTOR_2 |
1158 R128_YFACTOR_2 |
1159 R128_FLAT_SHADE_VERTEX_OGL |
1160 R128_FPU_ROUND_TRUNCATE |
1161 R128_WM_SEL_8DW);
1162
1163 rmesa->setup.setup_cntl = (R128_COLOR_GOURAUD |
1164 R128_PRIM_TYPE_TRI |
1165 R128_TEXTURE_ST_MULT_W |
1166 R128_STARTING_VERTEX_1 |
1167 R128_ENDING_VERTEX_3 |
1168 R128_SU_POLY_LINE_NOT_LAST |
1169 R128_SUB_PIX_4BITS);
1170
1171 rmesa->setup.tex_size_pitch_c = 0x00000000;
1172 rmesa->setup.constant_color_c = 0x00ffffff;
1173
1174 rmesa->setup.dp_write_mask = 0xffffffff;
1175 rmesa->setup.sten_ref_mask_c = 0xffff0000;
1176 rmesa->setup.plane_3d_mask_c = 0xffffffff;
1177
1178 rmesa->setup.window_xy_offset = 0x00000000;
1179
1180 rmesa->setup.scale_3d_cntl = (R128_SCALE_DITHER_TABLE |
1181 R128_TEX_CACHE_SIZE_FULL |
1182 R128_DITHER_INIT_RESET |
1183 R128_SCALE_3D_TEXMAP_SHADE |
1184 R128_SCALE_PIX_REPLICATE |
1185 R128_ALPHA_COMB_ADD_CLAMP |
1186 R128_FOG_VERTEX |
1187 (R128_ALPHA_BLEND_ONE << R128_ALPHA_BLEND_SRC_SHIFT) |
1188 (R128_ALPHA_BLEND_ZERO << R128_ALPHA_BLEND_DST_SHIFT) |
1189 R128_ALPHA_TEST_ALWAYS |
1190 R128_COMPOSITE_SHADOW_CMP_EQUAL |
1191 R128_TEX_MAP_ALPHA_IN_TEXTURE |
1192 R128_TEX_CACHE_LINE_SIZE_4QW);
1193
1194 rmesa->new_state = R128_NEW_ALL;
1195 }
1196
1197 /* Initialize the driver's state functions.
1198 */
1199 void r128DDInitStateFuncs( GLcontext *ctx )
1200 {
1201 ctx->Driver.UpdateState = r128DDInvalidateState;
1202
1203 ctx->Driver.ClearIndex = NULL;
1204 ctx->Driver.ClearColor = r128DDClearColor;
1205 ctx->Driver.DrawBuffer = r128DDDrawBuffer;
1206 ctx->Driver.ReadBuffer = r128DDReadBuffer;
1207
1208 ctx->Driver.IndexMask = NULL;
1209 ctx->Driver.ColorMask = r128DDColorMask;
1210 ctx->Driver.AlphaFunc = r128DDAlphaFunc;
1211 ctx->Driver.BlendEquationSeparate = r128DDBlendEquationSeparate;
1212 ctx->Driver.BlendFuncSeparate = r128DDBlendFuncSeparate;
1213 ctx->Driver.ClearDepth = r128DDClearDepth;
1214 ctx->Driver.CullFace = r128DDCullFace;
1215 ctx->Driver.FrontFace = r128DDFrontFace;
1216 ctx->Driver.DepthFunc = r128DDDepthFunc;
1217 ctx->Driver.DepthMask = r128DDDepthMask;
1218 ctx->Driver.Enable = r128DDEnable;
1219 ctx->Driver.Fogfv = r128DDFogfv;
1220 ctx->Driver.Hint = NULL;
1221 ctx->Driver.Lightfv = NULL;
1222 ctx->Driver.LightModelfv = r128DDLightModelfv;
1223 ctx->Driver.LogicOpcode = r128DDLogicOpCode;
1224 ctx->Driver.PolygonMode = NULL;
1225 ctx->Driver.PolygonStipple = r128DDPolygonStipple;
1226 ctx->Driver.RenderMode = r128DDRenderMode;
1227 ctx->Driver.Scissor = r128DDScissor;
1228 ctx->Driver.ShadeModel = r128DDShadeModel;
1229
1230 ctx->Driver.DepthRange = r128DepthRange;
1231 ctx->Driver.Viewport = r128Viewport;
1232
1233 /* Pixel path fallbacks.
1234 */
1235 ctx->Driver.Accum = _swrast_Accum;
1236 ctx->Driver.Bitmap = _swrast_Bitmap;
1237 ctx->Driver.CopyPixels = _swrast_CopyPixels;
1238 ctx->Driver.DrawPixels = _swrast_DrawPixels;
1239 ctx->Driver.ReadPixels = _swrast_ReadPixels;
1240
1241 /* Swrast hooks for imaging extensions:
1242 */
1243 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1244 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1245 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1246 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1247 }