1a4c32411533df47f2254a80c6f17cfd86250b1f
[mesa.git] / src / mesa / drivers / dri / sis / sis_state.c
1 /**************************************************************************
2
3 Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
4 Copyright 2003 Eric Anholt
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27 /* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */
28
29 /*
30 * Authors:
31 * Sung-Ching Lin <sclin@sis.com.tw>
32 * Eric Anholt <anholt@FreeBSD.org>
33 */
34
35 #include "sis_context.h"
36 #include "sis_state.h"
37 #include "sis_tris.h"
38 #include "sis_lock.h"
39 #include "sis_tex.h"
40
41 #include "context.h"
42 #include "enums.h"
43 #include "colormac.h"
44 #include "swrast/swrast.h"
45 #include "array_cache/acache.h"
46 #include "tnl/tnl.h"
47 #include "swrast_setup/swrast_setup.h"
48
49 #include "tnl/t_pipeline.h"
50
51 /* =============================================================
52 * Alpha blending
53 */
54
55 static void
56 sisDDAlphaFunc( GLcontext * ctx, GLenum func, GLfloat ref )
57 {
58 sisContextPtr smesa = SIS_CONTEXT(ctx);
59 GLubyte refbyte;
60
61 __GLSiSHardware *prev = &smesa->prev;
62 __GLSiSHardware *current = &smesa->current;
63
64 CLAMPED_FLOAT_TO_UBYTE(refbyte, ref);
65 current->hwAlpha = refbyte << 16;
66
67 /* Alpha Test function */
68 switch (func)
69 {
70 case GL_NEVER:
71 current->hwAlpha |= SiS_ALPHA_NEVER;
72 break;
73 case GL_LESS:
74 current->hwAlpha |= SiS_ALPHA_LESS;
75 break;
76 case GL_EQUAL:
77 current->hwAlpha |= SiS_ALPHA_EQUAL;
78 break;
79 case GL_LEQUAL:
80 current->hwAlpha |= SiS_ALPHA_LEQUAL;
81 break;
82 case GL_GREATER:
83 current->hwAlpha |= SiS_ALPHA_GREATER;
84 break;
85 case GL_NOTEQUAL:
86 current->hwAlpha |= SiS_ALPHA_NOTEQUAL;
87 break;
88 case GL_GEQUAL:
89 current->hwAlpha |= SiS_ALPHA_GEQUAL;
90 break;
91 case GL_ALWAYS:
92 current->hwAlpha |= SiS_ALPHA_ALWAYS;
93 break;
94 }
95
96 prev->hwAlpha = current->hwAlpha;
97 smesa->GlobalFlag |= GFLAG_ALPHASETTING;
98 }
99
100 static void
101 sisDDBlendFuncSeparate( GLcontext *ctx,
102 GLenum sfactorRGB, GLenum dfactorRGB,
103 GLenum sfactorA, GLenum dfactorA )
104 {
105 sisContextPtr smesa = SIS_CONTEXT(ctx);
106
107 __GLSiSHardware *prev = &smesa->prev;
108 __GLSiSHardware *current = &smesa->current;
109
110 current->hwDstSrcBlend = 0;
111
112 switch (dfactorRGB)
113 {
114 case GL_ZERO:
115 current->hwDstSrcBlend |= SiS_D_ZERO;
116 break;
117 case GL_ONE:
118 current->hwDstSrcBlend |= SiS_D_ONE;
119 break;
120 case GL_SRC_COLOR:
121 current->hwDstSrcBlend |= SiS_D_SRC_COLOR;
122 break;
123 case GL_ONE_MINUS_SRC_COLOR:
124 current->hwDstSrcBlend |= SiS_D_ONE_MINUS_SRC_COLOR;
125 break;
126 case GL_SRC_ALPHA:
127 current->hwDstSrcBlend |= SiS_D_SRC_ALPHA;
128 break;
129 case GL_ONE_MINUS_SRC_ALPHA:
130 current->hwDstSrcBlend |= SiS_D_ONE_MINUS_SRC_ALPHA;
131 break;
132 case GL_DST_COLOR:
133 current->hwDstSrcBlend |= SiS_D_DST_COLOR;
134 break;
135 case GL_ONE_MINUS_DST_COLOR:
136 current->hwDstSrcBlend |= SiS_D_ONE_MINUS_DST_COLOR;
137 break;
138 case GL_DST_ALPHA:
139 current->hwDstSrcBlend |= SiS_D_DST_ALPHA;
140 break;
141 case GL_ONE_MINUS_DST_ALPHA:
142 current->hwDstSrcBlend |= SiS_D_ONE_MINUS_DST_ALPHA;
143 break;
144 default:
145 fprintf(stderr, "Unknown dst blend function 0x%x\n", dfactorRGB);
146 break;
147 }
148
149 switch (sfactorRGB)
150 {
151 case GL_ZERO:
152 current->hwDstSrcBlend |= SiS_S_ZERO;
153 break;
154 case GL_ONE:
155 current->hwDstSrcBlend |= SiS_S_ONE;
156 break;
157 case GL_SRC_COLOR:
158 current->hwDstSrcBlend |= SiS_S_SRC_COLOR;
159 break;
160 case GL_ONE_MINUS_SRC_COLOR:
161 current->hwDstSrcBlend |= SiS_S_ONE_MINUS_SRC_COLOR;
162 break;
163 case GL_SRC_ALPHA:
164 current->hwDstSrcBlend |= SiS_S_SRC_ALPHA;
165 break;
166 case GL_ONE_MINUS_SRC_ALPHA:
167 current->hwDstSrcBlend |= SiS_S_ONE_MINUS_SRC_ALPHA;
168 break;
169 case GL_DST_COLOR:
170 current->hwDstSrcBlend |= SiS_S_DST_COLOR;
171 break;
172 case GL_ONE_MINUS_DST_COLOR:
173 current->hwDstSrcBlend |= SiS_S_ONE_MINUS_DST_COLOR;
174 break;
175 case GL_DST_ALPHA:
176 current->hwDstSrcBlend |= SiS_S_DST_ALPHA;
177 break;
178 case GL_ONE_MINUS_DST_ALPHA:
179 current->hwDstSrcBlend |= SiS_S_ONE_MINUS_DST_ALPHA;
180 break;
181 case GL_SRC_ALPHA_SATURATE:
182 current->hwDstSrcBlend |= SiS_S_SRC_ALPHA_SATURATE;
183 break;
184 default:
185 fprintf(stderr, "Unknown src blend function 0x%x\n", sfactorRGB);
186 break;
187 }
188
189 if (current->hwDstSrcBlend != prev->hwDstSrcBlend) {
190 prev->hwDstSrcBlend = current->hwDstSrcBlend;
191 smesa->GlobalFlag |= GFLAG_DSTBLEND;
192 }
193 }
194
195 /* =============================================================
196 * Depth testing
197 */
198
199 static void
200 sisDDDepthFunc( GLcontext * ctx, GLenum func )
201 {
202 sisContextPtr smesa = SIS_CONTEXT(ctx);
203 __GLSiSHardware *prev = &smesa->prev;
204 __GLSiSHardware *current = &smesa->current;
205
206 current->hwZ &= ~MASK_ZTestMode;
207 switch (func)
208 {
209 case GL_LESS:
210 current->hwZ |= SiS_Z_COMP_S_LT_B;
211 break;
212 case GL_GEQUAL:
213 current->hwZ |= SiS_Z_COMP_S_GE_B;
214 break;
215 case GL_LEQUAL:
216 current->hwZ |= SiS_Z_COMP_S_LE_B;
217 break;
218 case GL_GREATER:
219 current->hwZ |= SiS_Z_COMP_S_GT_B;
220 break;
221 case GL_NOTEQUAL:
222 current->hwZ |= SiS_Z_COMP_S_NE_B;
223 break;
224 case GL_EQUAL:
225 current->hwZ |= SiS_Z_COMP_S_EQ_B;
226 break;
227 case GL_ALWAYS:
228 current->hwZ |= SiS_Z_COMP_ALWAYS;
229 break;
230 case GL_NEVER:
231 current->hwZ |= SiS_Z_COMP_NEVER;
232 break;
233 }
234
235 if (current->hwZ != prev->hwZ) {
236 prev->hwZ = current->hwZ;
237 smesa->GlobalFlag |= GFLAG_ZSETTING;
238 }
239 }
240
241 void
242 sisDDDepthMask( GLcontext * ctx, GLboolean flag )
243 {
244 sisContextPtr smesa = SIS_CONTEXT(ctx);
245 __GLSiSHardware *prev = &smesa->prev;
246 __GLSiSHardware *current = &smesa->current;
247
248 if (!ctx->Depth.Test)
249 flag = GL_FALSE;
250
251 if (ctx->Visual.stencilBits) {
252 if (flag || (ctx->Stencil.WriteMask[0] != 0)) {
253 current->hwCapEnable |= MASK_ZWriteEnable;
254 if (flag && (ctx->Stencil.WriteMask[0] == 0xff)) {
255 current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable;
256 } else {
257 current->hwCapEnable2 |= MASK_ZMaskWriteEnable;
258 current->hwZMask = (ctx->Stencil.WriteMask[0] << 24) |
259 ((flag) ? 0x00ffffff : 0);
260
261 if (current->hwZMask ^ prev->hwZMask) {
262 prev->hwZMask = current->hwZMask;
263 smesa->GlobalFlag |= GFLAG_ZSETTING;
264 }
265 }
266 } else {
267 current->hwCapEnable &= ~MASK_ZWriteEnable;
268 }
269 } else {
270 if (flag) {
271 current->hwCapEnable |= MASK_ZWriteEnable;
272 current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable;
273 } else {
274 current->hwCapEnable &= ~MASK_ZWriteEnable;
275 }
276 }
277 }
278
279 /* =============================================================
280 * Clipping
281 */
282
283 void
284 sisUpdateClipping( GLcontext *ctx )
285 {
286 sisContextPtr smesa = SIS_CONTEXT(ctx);
287
288 __GLSiSHardware *prev = &smesa->prev;
289 __GLSiSHardware *current = &smesa->current;
290
291 GLint x1, y1, x2, y2;
292
293 if (smesa->is6326) {
294 /* XXX: 6326 has its own clipping for now. Should be fixed */
295 sis6326UpdateClipping(ctx);
296 return;
297 }
298
299 x1 = 0;
300 y1 = 0;
301 x2 = smesa->width - 1;
302 y2 = smesa->height - 1;
303
304 if (ctx->Scissor.Enabled) {
305 if (ctx->Scissor.X > x1)
306 x1 = ctx->Scissor.X;
307 if (ctx->Scissor.Y > y1)
308 y1 = ctx->Scissor.Y;
309 if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2)
310 x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
311 if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < y2)
312 y2 = ctx->Scissor.Y + ctx->Scissor.Height - 1;
313 }
314
315 y1 = Y_FLIP(y1);
316 y2 = Y_FLIP(y2);
317
318 current->clipTopBottom = (y2 << 13) | y1;
319 current->clipLeftRight = (x1 << 13) | x2;
320
321 if ((current->clipTopBottom ^ prev->clipTopBottom) ||
322 (current->clipLeftRight ^ prev->clipLeftRight))
323 {
324 prev->clipTopBottom = current->clipTopBottom;
325 prev->clipLeftRight = current->clipLeftRight;
326 smesa->GlobalFlag |= GFLAG_CLIPPING;
327 }
328 }
329
330 static void
331 sisDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
332 {
333 if (ctx->Scissor.Enabled)
334 sisUpdateClipping( ctx );
335 }
336
337 /* =============================================================
338 * Culling
339 */
340
341 static void
342 sisUpdateCull( GLcontext *ctx )
343 {
344 sisContextPtr smesa = SIS_CONTEXT(ctx);
345 GLint cullflag, frontface;
346
347 cullflag = ctx->Polygon.CullFaceMode;
348 frontface = ctx->Polygon.FrontFace;
349
350 smesa->AGPParseSet &= ~(MASK_PsCullDirection_CCW);
351 smesa->dwPrimitiveSet &= ~(MASK_CullDirection);
352
353 if((cullflag == GL_FRONT && frontface == GL_CCW) ||
354 (cullflag == GL_BACK && frontface == GL_CW))
355 {
356 smesa->AGPParseSet |= MASK_PsCullDirection_CCW;
357 smesa->dwPrimitiveSet |= OP_3D_CullDirection_CCW;
358 }
359 }
360
361
362 static void
363 sisDDCullFace( GLcontext *ctx, GLenum mode )
364 {
365 sisUpdateCull( ctx );
366 }
367
368 static void
369 sisDDFrontFace( GLcontext *ctx, GLenum mode )
370 {
371 sisUpdateCull( ctx );
372 }
373
374 /* =============================================================
375 * Masks
376 */
377
378 static void sisDDColorMask( GLcontext *ctx,
379 GLboolean r, GLboolean g,
380 GLboolean b, GLboolean a )
381 {
382 sisContextPtr smesa = SIS_CONTEXT(ctx);
383 __GLSiSHardware *prev = &smesa->prev;
384 __GLSiSHardware *current = &smesa->current;
385
386 if (r && g && b && ((ctx->Visual.alphaBits == 0) || a)) {
387 current->hwCapEnable2 &= ~(MASK_AlphaMaskWriteEnable |
388 MASK_ColorMaskWriteEnable);
389 } else {
390 current->hwCapEnable2 |= (MASK_AlphaMaskWriteEnable |
391 MASK_ColorMaskWriteEnable);
392
393 current->hwDstMask = (r) ? smesa->redMask : 0 |
394 (g) ? smesa->greenMask : 0 |
395 (b) ? smesa->blueMask : 0 |
396 (a) ? smesa->alphaMask : 0;
397 }
398
399 if (current->hwDstMask != prev->hwDstMask) {
400 prev->hwDstMask = current->hwDstMask;
401 smesa->GlobalFlag |= GFLAG_DESTSETTING;
402 }
403 }
404
405 /* =============================================================
406 * Rendering attributes
407 */
408
409 static void sisUpdateSpecular(GLcontext *ctx)
410 {
411 sisContextPtr smesa = SIS_CONTEXT(ctx);
412 __GLSiSHardware *current = &smesa->current;
413
414 if (NEED_SECONDARY_COLOR(ctx))
415 current->hwCapEnable |= MASK_SpecularEnable;
416 else
417 current->hwCapEnable &= ~MASK_SpecularEnable;
418 }
419
420 static void sisDDLightModelfv(GLcontext *ctx, GLenum pname,
421 const GLfloat *param)
422 {
423 if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
424 sisUpdateSpecular(ctx);
425 }
426 }
427
428 static void sisDDShadeModel( GLcontext *ctx, GLenum mode )
429 {
430 sisContextPtr smesa = SIS_CONTEXT(ctx);
431
432 /* Signal to sisRasterPrimitive to recalculate dwPrimitiveSet */
433 smesa->hw_primitive = -1;
434 }
435
436 /* =============================================================
437 * Window position
438 */
439
440 /* =============================================================
441 * Viewport
442 */
443
444 static void sisCalcViewport( GLcontext *ctx )
445 {
446 sisContextPtr smesa = SIS_CONTEXT(ctx);
447 const GLfloat *v = ctx->Viewport._WindowMap.m;
448 GLfloat *m = smesa->hw_viewport;
449
450 /* See also sis_translate_vertex.
451 */
452 m[MAT_SX] = v[MAT_SX];
453 m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
454 m[MAT_SY] = - v[MAT_SY];
455 m[MAT_TY] = - v[MAT_TY] + smesa->driDrawable->h + SUBPIXEL_Y;
456 m[MAT_SZ] = v[MAT_SZ] * smesa->depth_scale;
457 m[MAT_TZ] = v[MAT_TZ] * smesa->depth_scale;
458 }
459
460 static void sisDDViewport( GLcontext *ctx,
461 GLint x, GLint y,
462 GLsizei width, GLsizei height )
463 {
464 sisCalcViewport( ctx );
465 }
466
467 static void sisDDDepthRange( GLcontext *ctx,
468 GLclampd nearval, GLclampd farval )
469 {
470 sisCalcViewport( ctx );
471 }
472
473 /* =============================================================
474 * Miscellaneous
475 */
476
477 static void
478 sisDDLogicOpCode( GLcontext *ctx, GLenum opcode )
479 {
480 sisContextPtr smesa = SIS_CONTEXT(ctx);
481
482 __GLSiSHardware *prev = &smesa->prev;
483 __GLSiSHardware *current = &smesa->current;
484
485 current->hwDstSet &= ~MASK_ROP2;
486 switch (opcode)
487 {
488 case GL_CLEAR:
489 current->hwDstSet |= LOP_CLEAR;
490 break;
491 case GL_SET:
492 current->hwDstSet |= LOP_SET;
493 break;
494 case GL_COPY:
495 current->hwDstSet |= LOP_COPY;
496 break;
497 case GL_COPY_INVERTED:
498 current->hwDstSet |= LOP_COPY_INVERTED;
499 break;
500 case GL_NOOP:
501 current->hwDstSet |= LOP_NOOP;
502 break;
503 case GL_INVERT:
504 current->hwDstSet |= LOP_INVERT;
505 break;
506 case GL_AND:
507 current->hwDstSet |= LOP_AND;
508 break;
509 case GL_NAND:
510 current->hwDstSet |= LOP_NAND;
511 break;
512 case GL_OR:
513 current->hwDstSet |= LOP_OR;
514 break;
515 case GL_NOR:
516 current->hwDstSet |= LOP_NOR;
517 break;
518 case GL_XOR:
519 current->hwDstSet |= LOP_XOR;
520 break;
521 case GL_EQUIV:
522 current->hwDstSet |= LOP_EQUIV;
523 break;
524 case GL_AND_REVERSE:
525 current->hwDstSet |= LOP_AND_REVERSE;
526 break;
527 case GL_AND_INVERTED:
528 current->hwDstSet |= LOP_AND_INVERTED;
529 break;
530 case GL_OR_REVERSE:
531 current->hwDstSet |= LOP_OR_REVERSE;
532 break;
533 case GL_OR_INVERTED:
534 current->hwDstSet |= LOP_OR_INVERTED;
535 break;
536 }
537
538 if (current->hwDstSet ^ prev->hwDstSet) {
539 prev->hwDstSet = current->hwDstSet;
540 smesa->GlobalFlag |= GFLAG_DESTSETTING;
541 }
542 }
543
544 void sisDDDrawBuffer( GLcontext *ctx, GLenum mode )
545 {
546 sisContextPtr smesa = SIS_CONTEXT(ctx);
547 __GLSiSHardware *prev = &smesa->prev;
548 __GLSiSHardware *current = &smesa->current;
549
550 /*
551 * _DrawDestMask is easier to cope with than <mode>.
552 */
553 current->hwDstSet &= ~MASK_DstBufferPitch;
554 switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
555 case BUFFER_BIT_FRONT_LEFT:
556 FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE );
557 current->hwOffsetDest = smesa->front.offset >> 1;
558 current->hwDstSet |= smesa->front.pitch >> 2;
559 break;
560 case BUFFER_BIT_BACK_LEFT:
561 FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE );
562 current->hwOffsetDest = smesa->back.offset >> 1;
563 current->hwDstSet |= smesa->back.pitch >> 2;
564 break;
565 default:
566 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
567 FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_TRUE );
568 return;
569 }
570
571 if (current->hwDstSet != prev->hwDstSet) {
572 prev->hwDstSet = current->hwDstSet;
573 smesa->GlobalFlag |= GFLAG_DESTSETTING;
574 }
575
576 if (current->hwOffsetDest != prev->hwOffsetDest) {
577 prev->hwOffsetDest = current->hwOffsetDest;
578 smesa->GlobalFlag |= GFLAG_DESTSETTING;
579 }
580 }
581
582 /* =============================================================
583 * Polygon stipple
584 */
585
586 /* =============================================================
587 * Render mode
588 */
589
590 /* =============================================================
591 * State enable/disable
592 */
593
594 static void
595 sisDDEnable( GLcontext * ctx, GLenum cap, GLboolean state )
596 {
597 sisContextPtr smesa = SIS_CONTEXT(ctx);
598
599 __GLSiSHardware *current = &smesa->current;
600
601 switch (cap)
602 {
603 case GL_ALPHA_TEST:
604 if (state)
605 current->hwCapEnable |= MASK_AlphaTestEnable;
606 else
607 current->hwCapEnable &= ~MASK_AlphaTestEnable;
608 break;
609 case GL_BLEND:
610 /* TODO: */
611 if (state)
612 /* if (state & !ctx->Color.ColorLogicOpEnabled) */
613 current->hwCapEnable |= MASK_BlendEnable;
614 else
615 current->hwCapEnable &= ~MASK_BlendEnable;
616 break;
617 case GL_CULL_FACE:
618 if (state)
619 current->hwCapEnable |= MASK_CullEnable;
620 else
621 current->hwCapEnable &= ~MASK_CullEnable;
622 break;
623 case GL_DEPTH_TEST:
624 if (state && smesa->depth.offset != 0)
625 current->hwCapEnable |= MASK_ZTestEnable;
626 else
627 current->hwCapEnable &= ~MASK_ZTestEnable;
628 sisDDDepthMask( ctx, ctx->Depth.Mask );
629 break;
630 case GL_DITHER:
631 if (state)
632 current->hwCapEnable |= MASK_DitherEnable;
633 else
634 current->hwCapEnable &= ~MASK_DitherEnable;
635 break;
636 case GL_FOG:
637 if (state)
638 current->hwCapEnable |= MASK_FogEnable;
639 else
640 current->hwCapEnable &= ~MASK_FogEnable;
641 break;
642 case GL_COLOR_LOGIC_OP:
643 if (state)
644 sisDDLogicOpCode( ctx, ctx->Color.LogicOp );
645 else
646 sisDDLogicOpCode( ctx, GL_COPY );
647 break;
648 case GL_SCISSOR_TEST:
649 sisUpdateClipping( ctx );
650 break;
651 case GL_STENCIL_TEST:
652 if (state) {
653 if (smesa->zFormat != SiS_ZFORMAT_S8Z24)
654 FALLBACK(smesa, SIS_FALLBACK_STENCIL, 1);
655 else
656 current->hwCapEnable |= (MASK_StencilTestEnable |
657 MASK_StencilWriteEnable);
658 } else {
659 FALLBACK(smesa, SIS_FALLBACK_STENCIL, 0);
660 current->hwCapEnable &= ~(MASK_StencilTestEnable |
661 MASK_StencilWriteEnable);
662 }
663 break;
664 case GL_LIGHTING:
665 case GL_COLOR_SUM_EXT:
666 sisUpdateSpecular(ctx);
667 break;
668 }
669 }
670
671
672 /* =============================================================
673 * State initialization, management
674 */
675
676 /* Called before beginning of rendering. */
677 void
678 sisUpdateHWState( GLcontext *ctx )
679 {
680 sisContextPtr smesa = SIS_CONTEXT(ctx);
681 __GLSiSHardware *prev = &smesa->prev;
682 __GLSiSHardware *current = &smesa->current;
683
684 /* enable setting 1 */
685 if (current->hwCapEnable ^ prev->hwCapEnable) {
686 prev->hwCapEnable = current->hwCapEnable;
687 smesa->GlobalFlag |= GFLAG_ENABLESETTING;
688 }
689
690 /* enable setting 2 */
691 if (current->hwCapEnable2 ^ prev->hwCapEnable2) {
692 prev->hwCapEnable2 = current->hwCapEnable2;
693 smesa->GlobalFlag |= GFLAG_ENABLESETTING2;
694 }
695
696 if (smesa->GlobalFlag & GFLAG_RENDER_STATES)
697 sis_update_render_state( smesa );
698
699 if (smesa->GlobalFlag & GFLAG_TEXTURE_STATES)
700 sis_update_texture_state( smesa );
701 }
702
703 static void
704 sisDDInvalidateState( GLcontext *ctx, GLuint new_state )
705 {
706 sisContextPtr smesa = SIS_CONTEXT(ctx);
707
708 _swrast_InvalidateState( ctx, new_state );
709 _swsetup_InvalidateState( ctx, new_state );
710 _ac_InvalidateState( ctx, new_state );
711 _tnl_InvalidateState( ctx, new_state );
712 smesa->NewGLState |= new_state;
713 }
714
715 /* Initialize the context's hardware state.
716 */
717 void sisDDInitState( sisContextPtr smesa )
718 {
719 __GLSiSHardware *current = &smesa->current;
720 __GLSiSHardware *prev = &(smesa->prev);
721 GLcontext *ctx = smesa->glCtx;
722
723 /* add Texture Perspective Enable */
724 prev->hwCapEnable = MASK_FogPerspectiveEnable | MASK_TextureCacheEnable |
725 MASK_TexturePerspectiveEnable | MASK_DitherEnable;
726
727 /*
728 prev->hwCapEnable2 = 0x00aa0080;
729 */
730 /* if multi-texture enabled, disable Z pre-test */
731 prev->hwCapEnable2 = MASK_TextureMipmapBiasEnable;
732
733 /* Z test mode is LESS */
734 prev->hwZ = SiS_Z_COMP_S_LT_B;
735
736 /* Depth mask */
737 prev->hwZMask = 0xffffffff;
738
739 /* Alpha test mode is ALWAYS, alpha ref value is 0 */
740 prev->hwAlpha = SiS_ALPHA_ALWAYS;
741
742 /* ROP2 is COPYPEN */
743 prev->hwDstSet = LOP_COPY;
744
745 /* color mask */
746 prev->hwDstMask = 0xffffffff;
747
748 /* LinePattern is 0, Repeat Factor is 0 */
749 prev->hwLinePattern = 0x00008000;
750
751 /* Src blend is BLEND_ONE, Dst blend is D3DBLEND_ZERO */
752 prev->hwDstSrcBlend = SiS_S_ONE | SiS_D_ZERO;
753
754 /* Stenciling disabled, function ALWAYS, ref value zero, mask all ones */
755 prev->hwStSetting = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS | 0xff;
756 /* Op is KEEP for all three operations */
757 prev->hwStSetting2 = SiS_SFAIL_KEEP | SiS_SPASS_ZFAIL_KEEP |
758 SiS_SPASS_ZPASS_KEEP;
759
760 /* Texture mapping mode is Tile */
761 #if 0
762 prev->texture[0].hwTextureSet = 0x00030000;
763 #endif
764 /* Magnified & minified texture filter is NEAREST */
765 #if 0
766 prev->texture[0].hwTextureMip = 0;
767 #endif
768
769 /* Texture Blending setting -- use fragment color/alpha*/
770 prev->hwTexBlendColor0 = STAGE0_C_CF;
771 prev->hwTexBlendColor1 = STAGE1_C_CF;
772 prev->hwTexBlendAlpha0 = STAGE0_A_AF;
773 prev->hwTexBlendAlpha1 = STAGE1_A_AF;
774
775 switch (smesa->bytesPerPixel)
776 {
777 case 2:
778 prev->hwDstSet |= DST_FORMAT_RGB_565;
779 break;
780 case 4:
781 prev->hwDstSet |= DST_FORMAT_ARGB_8888;
782 break;
783 }
784
785 switch (ctx->Visual.depthBits)
786 {
787 case 0:
788 prev->hwCapEnable &= ~MASK_ZWriteEnable;
789 case 16:
790 smesa->zFormat = SiS_ZFORMAT_Z16;
791 prev->hwCapEnable |= MASK_ZWriteEnable;
792 smesa->depth_scale = 1.0 / (GLfloat)0xffff;
793 break;
794 case 32:
795 smesa->zFormat = SiS_ZFORMAT_Z32;
796 prev->hwCapEnable |= MASK_ZWriteEnable;
797 smesa->depth_scale = 1.0 / (GLfloat)0xffffffff;
798 break;
799 case 24:
800 assert (ctx->Visual.stencilBits);
801 smesa->zFormat = SiS_ZFORMAT_S8Z24;
802 prev->hwCapEnable |= MASK_StencilBufferEnable;
803 prev->hwCapEnable |= MASK_ZWriteEnable;
804 smesa->depth_scale = 1.0 / (GLfloat)0xffffff;
805 break;
806 }
807
808 prev->hwZ |= smesa->zFormat;
809
810 /* TODO: need to clear cache? */
811 smesa->clearTexCache = GL_TRUE;
812
813 smesa->clearColorPattern = 0;
814
815 smesa->AGPParseSet = MASK_PsTexture1FromB | MASK_PsBumpTextureFromC;
816 smesa->dwPrimitiveSet = OP_3D_Texture1FromB | OP_3D_TextureBumpFromC;
817
818 sisUpdateZStencilPattern( smesa, 1.0, 0 );
819 sisUpdateCull( ctx );
820
821 memcpy( current, prev, sizeof (__GLSiSHardware) );
822
823 /* Set initial fog settings. Start and end are the same case. */
824 sisDDFogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
825 sisDDFogfv( ctx, GL_FOG_END, &ctx->Fog.End );
826 sisDDFogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL );
827 sisDDFogfv( ctx, GL_FOG_MODE, NULL );
828 }
829
830 /* Initialize the driver's state functions.
831 */
832 void sisDDInitStateFuncs( GLcontext *ctx )
833 {
834 ctx->Driver.UpdateState = sisDDInvalidateState;
835
836 ctx->Driver.Clear = sisDDClear;
837 ctx->Driver.ClearColor = sisDDClearColor;
838 ctx->Driver.ClearDepth = sisDDClearDepth;
839 ctx->Driver.ClearStencil = sisDDClearStencil;
840
841 ctx->Driver.AlphaFunc = sisDDAlphaFunc;
842 ctx->Driver.BlendFuncSeparate = sisDDBlendFuncSeparate;
843 ctx->Driver.ColorMask = sisDDColorMask;
844 ctx->Driver.CullFace = sisDDCullFace;
845 ctx->Driver.DepthMask = sisDDDepthMask;
846 ctx->Driver.DepthFunc = sisDDDepthFunc;
847 ctx->Driver.DepthRange = sisDDDepthRange;
848 ctx->Driver.DrawBuffer = sisDDDrawBuffer;
849 ctx->Driver.Enable = sisDDEnable;
850 ctx->Driver.FrontFace = sisDDFrontFace;
851 ctx->Driver.Fogfv = sisDDFogfv;
852 ctx->Driver.Hint = NULL;
853 ctx->Driver.Lightfv = NULL;
854 ctx->Driver.LogicOpcode = sisDDLogicOpCode;
855 ctx->Driver.PolygonMode = NULL;
856 ctx->Driver.PolygonStipple = NULL;
857 ctx->Driver.ReadBuffer = NULL;
858 ctx->Driver.RenderMode = NULL;
859 ctx->Driver.Scissor = sisDDScissor;
860 ctx->Driver.ShadeModel = sisDDShadeModel;
861 ctx->Driver.LightModelfv = sisDDLightModelfv;
862 ctx->Driver.Viewport = sisDDViewport;
863
864 /* Pixel path fallbacks. */
865 ctx->Driver.Accum = _swrast_Accum;
866 ctx->Driver.Bitmap = _swrast_Bitmap;
867 ctx->Driver.CopyPixels = _swrast_CopyPixels;
868 ctx->Driver.DrawPixels = _swrast_DrawPixels;
869 ctx->Driver.ReadPixels = _swrast_ReadPixels;
870
871 ctx->Driver.ResizeBuffers = sisReAllocateBuffers;
872 /* Swrast hooks for imaging extensions:
873 */
874 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
875 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
876 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
877 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
878 }