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