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