Fixed off by one errors in clipping.
[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 x1 = 0;
294 y1 = 0;
295 x2 = smesa->width - 1;
296 y2 = smesa->height - 1;
297
298 if (ctx->Scissor.Enabled) {
299 if (ctx->Scissor.X > x1)
300 x1 = ctx->Scissor.X;
301 if (ctx->Scissor.Y > y1)
302 y1 = ctx->Scissor.Y;
303 if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2)
304 x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
305 if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < y2)
306 y2 = ctx->Scissor.Y + ctx->Scissor.Height - 1;
307 }
308
309 y1 = Y_FLIP(y1);
310 y2 = Y_FLIP(y2);
311
312 current->clipTopBottom = (y2 << 13) | y1;
313 current->clipLeftRight = (x1 << 13) | x2;
314
315 if ((current->clipTopBottom ^ prev->clipTopBottom) ||
316 (current->clipLeftRight ^ prev->clipLeftRight))
317 {
318 prev->clipTopBottom = current->clipTopBottom;
319 prev->clipLeftRight = current->clipLeftRight;
320 smesa->GlobalFlag |= GFLAG_CLIPPING;
321 }
322 }
323
324 static void
325 sisDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
326 {
327 if (ctx->Scissor.Enabled)
328 sisUpdateClipping( ctx );
329 }
330
331 /* =============================================================
332 * Culling
333 */
334
335 static void
336 sisUpdateCull( GLcontext *ctx )
337 {
338 sisContextPtr smesa = SIS_CONTEXT(ctx);
339 GLint cullflag, frontface;
340
341 cullflag = ctx->Polygon.CullFaceMode;
342 frontface = ctx->Polygon.FrontFace;
343
344 smesa->AGPParseSet &= ~(MASK_PsCullDirection_CCW);
345 smesa->dwPrimitiveSet &= ~(MASK_CullDirection);
346
347 if((cullflag == GL_FRONT && frontface == GL_CCW) ||
348 (cullflag == GL_BACK && frontface == GL_CW))
349 {
350 smesa->AGPParseSet |= MASK_PsCullDirection_CCW;
351 smesa->dwPrimitiveSet |= OP_3D_CullDirection_CCW;
352 }
353 }
354
355
356 static void
357 sisDDCullFace( GLcontext *ctx, GLenum mode )
358 {
359 sisUpdateCull( ctx );
360 }
361
362 static void
363 sisDDFrontFace( GLcontext *ctx, GLenum mode )
364 {
365 sisUpdateCull( ctx );
366 }
367
368 /* =============================================================
369 * Masks
370 */
371
372 static void sisDDColorMask( GLcontext *ctx,
373 GLboolean r, GLboolean g,
374 GLboolean b, GLboolean a )
375 {
376 sisContextPtr smesa = SIS_CONTEXT(ctx);
377 __GLSiSHardware *prev = &smesa->prev;
378 __GLSiSHardware *current = &smesa->current;
379
380 if (r && g && b && ((ctx->Visual.alphaBits == 0) || a)) {
381 current->hwCapEnable2 &= ~(MASK_AlphaMaskWriteEnable |
382 MASK_ColorMaskWriteEnable);
383 } else {
384 current->hwCapEnable2 |= (MASK_AlphaMaskWriteEnable |
385 MASK_ColorMaskWriteEnable);
386
387 current->hwDstMask = (r) ? smesa->redMask : 0 |
388 (g) ? smesa->greenMask : 0 |
389 (b) ? smesa->blueMask : 0 |
390 (a) ? smesa->alphaMask : 0;
391 }
392
393 if (current->hwDstMask != prev->hwDstMask) {
394 prev->hwDstMask = current->hwDstMask;
395 smesa->GlobalFlag |= GFLAG_DESTSETTING;
396 }
397 }
398
399 /* =============================================================
400 * Rendering attributes
401 */
402
403 static void sisDDShadeModel( GLcontext *ctx, GLenum mode )
404 {
405 sisContextPtr smesa = SIS_CONTEXT(ctx);
406
407 /* Signal to sisRasterPrimitive to recalculate dwPrimitiveSet */
408 smesa->hw_primitive = -1;
409 }
410
411 /* =============================================================
412 * Window position
413 */
414
415 /* =============================================================
416 * Viewport
417 */
418
419 static void sisCalcViewport( GLcontext *ctx )
420 {
421 sisContextPtr smesa = SIS_CONTEXT(ctx);
422 const GLfloat *v = ctx->Viewport._WindowMap.m;
423 GLfloat *m = smesa->hw_viewport;
424
425 /* See also sis_translate_vertex.
426 */
427 m[MAT_SX] = v[MAT_SX];
428 m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
429 m[MAT_SY] = - v[MAT_SY];
430 m[MAT_TY] = - v[MAT_TY] + smesa->driDrawable->h + SUBPIXEL_Y;
431 m[MAT_SZ] = v[MAT_SZ] * smesa->depth_scale;
432 m[MAT_TZ] = v[MAT_TZ] * smesa->depth_scale;
433 }
434
435 static void sisDDViewport( GLcontext *ctx,
436 GLint x, GLint y,
437 GLsizei width, GLsizei height )
438 {
439 sisCalcViewport( ctx );
440 }
441
442 static void sisDDDepthRange( GLcontext *ctx,
443 GLclampd nearval, GLclampd farval )
444 {
445 sisCalcViewport( ctx );
446 }
447
448 /* =============================================================
449 * Miscellaneous
450 */
451
452 static void
453 sisDDLogicOpCode( GLcontext *ctx, GLenum opcode )
454 {
455 sisContextPtr smesa = SIS_CONTEXT(ctx);
456
457 __GLSiSHardware *prev = &smesa->prev;
458 __GLSiSHardware *current = &smesa->current;
459
460 current->hwDstSet &= ~MASK_ROP2;
461 switch (opcode)
462 {
463 case GL_CLEAR:
464 current->hwDstSet |= LOP_CLEAR;
465 break;
466 case GL_SET:
467 current->hwDstSet |= LOP_SET;
468 break;
469 case GL_COPY:
470 current->hwDstSet |= LOP_COPY;
471 break;
472 case GL_COPY_INVERTED:
473 current->hwDstSet |= LOP_COPY_INVERTED;
474 break;
475 case GL_NOOP:
476 current->hwDstSet |= LOP_NOOP;
477 break;
478 case GL_INVERT:
479 current->hwDstSet |= LOP_INVERT;
480 break;
481 case GL_AND:
482 current->hwDstSet |= LOP_AND;
483 break;
484 case GL_NAND:
485 current->hwDstSet |= LOP_NAND;
486 break;
487 case GL_OR:
488 current->hwDstSet |= LOP_OR;
489 break;
490 case GL_NOR:
491 current->hwDstSet |= LOP_NOR;
492 break;
493 case GL_XOR:
494 current->hwDstSet |= LOP_XOR;
495 break;
496 case GL_EQUIV:
497 current->hwDstSet |= LOP_EQUIV;
498 break;
499 case GL_AND_REVERSE:
500 current->hwDstSet |= LOP_AND_REVERSE;
501 break;
502 case GL_AND_INVERTED:
503 current->hwDstSet |= LOP_AND_INVERTED;
504 break;
505 case GL_OR_REVERSE:
506 current->hwDstSet |= LOP_OR_REVERSE;
507 break;
508 case GL_OR_INVERTED:
509 current->hwDstSet |= LOP_OR_INVERTED;
510 break;
511 }
512
513 if (current->hwDstSet ^ prev->hwDstSet) {
514 prev->hwDstSet = current->hwDstSet;
515 smesa->GlobalFlag |= GFLAG_DESTSETTING;
516 }
517 }
518
519 void sisDDDrawBuffer( GLcontext *ctx, GLenum mode )
520 {
521 sisContextPtr smesa = SIS_CONTEXT(ctx);
522
523 __GLSiSHardware *prev = &smesa->prev;
524 __GLSiSHardware *current = &smesa->current;
525
526 /*
527 * _DrawDestMask is easier to cope with than <mode>.
528 */
529 switch ( ctx->Color._DrawDestMask[0] ) {
530 case DD_FRONT_LEFT_BIT:
531 case DD_BACK_LEFT_BIT:
532 FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE );
533 break;
534 default:
535 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
536 FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_TRUE );
537 return;
538 }
539
540 /* We want to update the s/w rast state too so that sisDDSetBuffer()
541 * gets called.
542 */
543 _swrast_DrawBuffer(ctx, mode);
544
545 current->hwOffsetDest = (smesa->drawOffset) >> 1;
546 current->hwDstSet &= ~MASK_DstBufferPitch;
547 current->hwDstSet |= smesa->drawPitch >> 2;
548
549 if (current->hwDstSet != prev->hwDstSet) {
550 prev->hwDstSet = current->hwDstSet;
551 smesa->GlobalFlag |= GFLAG_DESTSETTING;
552 }
553
554 if (current->hwOffsetDest != prev->hwOffsetDest) {
555 prev->hwOffsetDest = current->hwOffsetDest;
556 smesa->GlobalFlag |= GFLAG_DESTSETTING;
557 }
558 }
559
560 /* =============================================================
561 * Polygon stipple
562 */
563
564 /* =============================================================
565 * Render mode
566 */
567
568 /* =============================================================
569 * State enable/disable
570 */
571
572 static void
573 sisDDEnable( GLcontext * ctx, GLenum cap, GLboolean state )
574 {
575 sisContextPtr smesa = SIS_CONTEXT(ctx);
576
577 __GLSiSHardware *current = &smesa->current;
578
579 switch (cap)
580 {
581 case GL_ALPHA_TEST:
582 if (state)
583 current->hwCapEnable |= MASK_AlphaTestEnable;
584 else
585 current->hwCapEnable &= ~MASK_AlphaTestEnable;
586 break;
587 case GL_BLEND:
588 /* TODO: */
589 if (state)
590 /* if (state & !ctx->Color.ColorLogicOpEnabled) */
591 current->hwCapEnable |= MASK_BlendEnable;
592 else
593 current->hwCapEnable &= ~MASK_BlendEnable;
594 break;
595 case GL_CULL_FACE:
596 if (state)
597 current->hwCapEnable |= MASK_CullEnable;
598 else
599 current->hwCapEnable &= ~MASK_CullEnable;
600 break;
601 case GL_DEPTH_TEST:
602 if (state && smesa->depthbuffer)
603 current->hwCapEnable |= MASK_ZTestEnable;
604 else
605 current->hwCapEnable &= ~MASK_ZTestEnable;
606 sisDDDepthMask( ctx, ctx->Depth.Mask );
607 break;
608 case GL_DITHER:
609 if (state)
610 current->hwCapEnable |= MASK_DitherEnable;
611 else
612 current->hwCapEnable &= ~MASK_DitherEnable;
613 break;
614 case GL_FOG:
615 if (state)
616 current->hwCapEnable |= MASK_FogEnable;
617 else
618 current->hwCapEnable &= ~MASK_FogEnable;
619 break;
620 case GL_COLOR_LOGIC_OP:
621 if (state)
622 sisDDLogicOpCode( ctx, ctx->Color.LogicOp );
623 else
624 sisDDLogicOpCode( ctx, GL_COPY );
625 break;
626 case GL_SCISSOR_TEST:
627 sisUpdateClipping( ctx );
628 break;
629 case GL_STENCIL_TEST:
630 if (state) {
631 if (smesa->zFormat != SiS_ZFORMAT_S8Z24)
632 FALLBACK(smesa, SIS_FALLBACK_STENCIL, 1);
633 else
634 current->hwCapEnable |= (MASK_StencilTestEnable |
635 MASK_StencilWriteEnable);
636 } else {
637 FALLBACK(smesa, SIS_FALLBACK_STENCIL, 0);
638 current->hwCapEnable &= ~(MASK_StencilTestEnable |
639 MASK_StencilWriteEnable);
640 }
641 break;
642 }
643 }
644
645
646 /* =============================================================
647 * State initialization, management
648 */
649
650 /* Called before beginning of rendering. */
651 void
652 sisUpdateHWState( GLcontext *ctx )
653 {
654 sisContextPtr smesa = SIS_CONTEXT(ctx);
655 __GLSiSHardware *prev = &smesa->prev;
656 __GLSiSHardware *current = &smesa->current;
657
658 /* enable setting 1 */
659 if (current->hwCapEnable ^ prev->hwCapEnable) {
660 prev->hwCapEnable = current->hwCapEnable;
661 smesa->GlobalFlag |= GFLAG_ENABLESETTING;
662 }
663
664 /* enable setting 2 */
665 if (current->hwCapEnable2 ^ prev->hwCapEnable2) {
666 prev->hwCapEnable2 = current->hwCapEnable2;
667 smesa->GlobalFlag |= GFLAG_ENABLESETTING2;
668 }
669
670 if (smesa->GlobalFlag & GFLAG_RENDER_STATES)
671 sis_update_render_state( smesa );
672
673 if (smesa->GlobalFlag & GFLAG_TEXTURE_STATES)
674 sis_update_texture_state( smesa );
675 }
676
677 static void
678 sisDDInvalidateState( GLcontext *ctx, GLuint new_state )
679 {
680 sisContextPtr smesa = SIS_CONTEXT(ctx);
681
682 _swrast_InvalidateState( ctx, new_state );
683 _swsetup_InvalidateState( ctx, new_state );
684 _ac_InvalidateState( ctx, new_state );
685 _tnl_InvalidateState( ctx, new_state );
686 smesa->NewGLState |= new_state;
687 }
688
689 /* Initialize the context's hardware state.
690 */
691 void sisDDInitState( sisContextPtr smesa )
692 {
693 __GLSiSHardware *current = &smesa->current;
694 __GLSiSHardware *prev = &(smesa->prev);
695 GLcontext *ctx = smesa->glCtx;
696
697 /* add Texture Perspective Enable */
698 prev->hwCapEnable = MASK_FogPerspectiveEnable | MASK_TextureCacheEnable |
699 MASK_TexturePerspectiveEnable | MASK_DitherEnable;
700 /*| MASK_SpecularEnable*/
701
702 /*
703 prev->hwCapEnable2 = 0x00aa0080;
704 */
705 /* if multi-texture enabled, disable Z pre-test */
706 prev->hwCapEnable2 = MASK_TextureMipmapBiasEnable;
707
708 /* Z test mode is LESS */
709 prev->hwZ = SiS_Z_COMP_S_LT_B;
710
711 /* Depth mask */
712 prev->hwZMask = 0xffffffff;
713
714 /* Alpha test mode is ALWAYS, alpha ref value is 0 */
715 prev->hwAlpha = SiS_ALPHA_ALWAYS;
716
717 /* ROP2 is COPYPEN */
718 prev->hwDstSet = LOP_COPY;
719
720 /* color mask */
721 prev->hwDstMask = 0xffffffff;
722
723 /* LinePattern is 0, Repeat Factor is 0 */
724 prev->hwLinePattern = 0x00008000;
725
726 /* Src blend is BLEND_ONE, Dst blend is D3DBLEND_ZERO */
727 prev->hwDstSrcBlend = SiS_S_ONE | SiS_D_ZERO;
728
729 /* Stenciling disabled, function ALWAYS, ref value zero, mask all ones */
730 prev->hwStSetting = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS | 0xff;
731 /* Op is KEEP for all three operations */
732 prev->hwStSetting2 = SiS_SFAIL_KEEP | SiS_SPASS_ZFAIL_KEEP |
733 SiS_SPASS_ZPASS_KEEP;
734
735 /* Texture mapping mode is Tile */
736 #if 0
737 prev->texture[0].hwTextureSet = 0x00030000;
738 #endif
739 /* Magnified & minified texture filter is NEAREST */
740 #if 0
741 prev->texture[0].hwTextureMip = 0;
742 #endif
743
744 /* Texture Blending setting -- use fragment color/alpha*/
745 prev->hwTexBlendColor0 = STAGE0_C_CF;
746 prev->hwTexBlendColor1 = STAGE1_C_CF;
747 prev->hwTexBlendAlpha0 = STAGE0_A_AF;
748 prev->hwTexBlendAlpha1 = STAGE1_A_AF;
749
750 switch (smesa->bytesPerPixel)
751 {
752 case 2:
753 prev->hwDstSet |= DST_FORMAT_RGB_565;
754 break;
755 case 4:
756 prev->hwDstSet |= DST_FORMAT_ARGB_8888;
757 break;
758 }
759
760 switch (ctx->Visual.depthBits)
761 {
762 case 0:
763 prev->hwCapEnable &= ~MASK_ZWriteEnable;
764 case 16:
765 smesa->zFormat = SiS_ZFORMAT_Z16;
766 prev->hwCapEnable |= MASK_ZWriteEnable;
767 smesa->depth_scale = 1.0 / (GLfloat)0xffff;
768 break;
769 case 32:
770 smesa->zFormat = SiS_ZFORMAT_Z32;
771 prev->hwCapEnable |= MASK_ZWriteEnable;
772 smesa->depth_scale = 1.0 / (GLfloat)0xffffffff;
773 break;
774 case 24:
775 assert (ctx->Visual.stencilBits);
776 smesa->zFormat = SiS_ZFORMAT_S8Z24;
777 prev->hwCapEnable |= MASK_StencilBufferEnable;
778 prev->hwCapEnable |= MASK_ZWriteEnable;
779 smesa->depth_scale = 1.0 / (GLfloat)0xffffff;
780 break;
781 }
782
783 prev->hwZ |= smesa->zFormat;
784
785 /* TODO: need to clear cache? */
786 smesa->clearTexCache = GL_TRUE;
787
788 smesa->clearColorPattern = 0;
789
790 smesa->AGPParseSet = MASK_PsTexture1FromB | MASK_PsBumpTextureFromC;
791 smesa->dwPrimitiveSet = OP_3D_Texture1FromB | OP_3D_TextureBumpFromC;
792
793 sisUpdateZStencilPattern( smesa, 1.0, 0 );
794 sisUpdateCull( ctx );
795
796 memcpy( current, prev, sizeof (__GLSiSHardware) );
797
798 /* Set initial fog settings. Start and end are the same case. */
799 sisDDFogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
800 sisDDFogfv( ctx, GL_FOG_END, &ctx->Fog.End );
801 sisDDFogfv( ctx, GL_FOG_MODE, NULL );
802 }
803
804 /* Initialize the driver's state functions.
805 */
806 void sisDDInitStateFuncs( GLcontext *ctx )
807 {
808 ctx->Driver.UpdateState = sisDDInvalidateState;
809
810 ctx->Driver.Clear = sisDDClear;
811 ctx->Driver.ClearColor = sisDDClearColor;
812 ctx->Driver.ClearDepth = sisDDClearDepth;
813 ctx->Driver.ClearStencil = sisDDClearStencil;
814
815 ctx->Driver.AlphaFunc = sisDDAlphaFunc;
816 ctx->Driver.BlendFuncSeparate = sisDDBlendFuncSeparate;
817 ctx->Driver.ColorMask = sisDDColorMask;
818 ctx->Driver.CullFace = sisDDCullFace;
819 ctx->Driver.DepthMask = sisDDDepthMask;
820 ctx->Driver.DepthFunc = sisDDDepthFunc;
821 ctx->Driver.DepthRange = sisDDDepthRange;
822 ctx->Driver.DrawBuffer = sisDDDrawBuffer;
823 ctx->Driver.Enable = sisDDEnable;
824 ctx->Driver.FrontFace = sisDDFrontFace;
825 ctx->Driver.Fogfv = sisDDFogfv;
826 ctx->Driver.Hint = NULL;
827 ctx->Driver.Lightfv = NULL;
828 ctx->Driver.LogicOpcode = sisDDLogicOpCode;
829 ctx->Driver.PolygonMode = NULL;
830 ctx->Driver.PolygonStipple = NULL;
831 ctx->Driver.ReadBuffer = NULL;
832 ctx->Driver.RenderMode = NULL;
833 ctx->Driver.Scissor = sisDDScissor;
834 ctx->Driver.ShadeModel = sisDDShadeModel;
835 ctx->Driver.Viewport = sisDDViewport;
836
837 /* Pixel path fallbacks. */
838 ctx->Driver.Accum = _swrast_Accum;
839 ctx->Driver.Bitmap = _swrast_Bitmap;
840 ctx->Driver.CopyPixels = _swrast_CopyPixels;
841 ctx->Driver.DrawPixels = _swrast_DrawPixels;
842 ctx->Driver.ReadPixels = _swrast_ReadPixels;
843
844 /* Swrast hooks for imaging extensions:
845 */
846 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
847 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
848 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
849 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
850 }