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