Merge branch 'master' of git+ssh://git.freedesktop.org/git/mesa/mesa into gallium-0.2
[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 if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
550 FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_TRUE );
551 return;
552 }
553
554 current->hwDstSet &= ~MASK_DstBufferPitch;
555 switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
556 case BUFFER_FRONT_LEFT:
557 FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE );
558 current->hwOffsetDest = smesa->front.offset >> 1;
559 current->hwDstSet |= smesa->front.pitch >> 2;
560 break;
561 case BUFFER_BACK_LEFT:
562 FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE );
563 current->hwOffsetDest = smesa->back.offset >> 1;
564 current->hwDstSet |= smesa->back.pitch >> 2;
565 break;
566 default:
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 _vbo_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 /* XXX this should go away */
865 ctx->Driver.ResizeBuffers = sisReAllocateBuffers;
866 }