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