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