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