2 * Copyright 2005 Eric Anholt
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Eric Anholt <anholt@FreeBSD.org>
29 #include "sis_context.h"
30 #include "sis_state.h"
39 #include "swrast/swrast.h"
42 #include "swrast_setup/swrast_setup.h"
44 #include "tnl/t_pipeline.h"
46 /* =============================================================
51 sis6326DDAlphaFunc( GLcontext
*ctx
, GLenum func
, GLfloat ref
)
53 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
56 __GLSiSHardware
*prev
= &smesa
->prev
;
57 __GLSiSHardware
*current
= &smesa
->current
;
59 CLAMPED_FLOAT_TO_UBYTE(refbyte
, ref
);
60 current
->hwAlpha
= refbyte
<< 16;
62 /* Alpha Test function */
66 current
->hwAlpha
|= S_ASET_PASS_NEVER
;
69 current
->hwAlpha
|= S_ASET_PASS_LESS
;
72 current
->hwAlpha
|= S_ASET_PASS_EQUAL
;
75 current
->hwAlpha
|= S_ASET_PASS_LEQUAL
;
78 current
->hwAlpha
|= S_ASET_PASS_GREATER
;
81 current
->hwAlpha
|= S_ASET_PASS_NOTEQUAL
;
84 current
->hwAlpha
|= S_ASET_PASS_GEQUAL
;
87 current
->hwAlpha
|= S_ASET_PASS_ALWAYS
;
91 prev
->hwAlpha
= current
->hwAlpha
;
92 smesa
->GlobalFlag
|= GFLAG_ALPHASETTING
;
96 sis6326DDBlendFuncSeparate( GLcontext
*ctx
,
97 GLenum sfactorRGB
, GLenum dfactorRGB
,
98 GLenum sfactorA
, GLenum dfactorA
)
100 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
102 __GLSiSHardware
*prev
= &smesa
->prev
;
103 __GLSiSHardware
*current
= &smesa
->current
;
105 current
->hwDstSrcBlend
= 0;
110 current
->hwDstSrcBlend
|= S_DBLEND_ZERO
;
113 current
->hwDstSrcBlend
|= S_DBLEND_ONE
;
116 current
->hwDstSrcBlend
|= S_DBLEND_SRC_COLOR
;
118 case GL_ONE_MINUS_SRC_COLOR
:
119 current
->hwDstSrcBlend
|= S_DBLEND_INV_SRC_COLOR
;
122 current
->hwDstSrcBlend
|= S_DBLEND_SRC_ALPHA
;
124 case GL_ONE_MINUS_SRC_ALPHA
:
125 current
->hwDstSrcBlend
|= S_DBLEND_INV_SRC_ALPHA
;
128 current
->hwDstSrcBlend
|= S_DBLEND_DST_ALPHA
;
130 case GL_ONE_MINUS_DST_ALPHA
:
131 current
->hwDstSrcBlend
|= S_DBLEND_INV_DST_ALPHA
;
138 current
->hwDstSrcBlend
|= S_SBLEND_ZERO
;
141 current
->hwDstSrcBlend
|= S_SBLEND_ONE
;
144 current
->hwDstSrcBlend
|= S_SBLEND_SRC_ALPHA
;
146 case GL_ONE_MINUS_SRC_ALPHA
:
147 current
->hwDstSrcBlend
|= S_SBLEND_INV_SRC_ALPHA
;
150 current
->hwDstSrcBlend
|= S_SBLEND_DST_ALPHA
;
152 case GL_ONE_MINUS_DST_ALPHA
:
153 current
->hwDstSrcBlend
|= S_SBLEND_INV_DST_ALPHA
;
156 current
->hwDstSrcBlend
|= S_SBLEND_DST_COLOR
;
158 case GL_ONE_MINUS_DST_COLOR
:
159 current
->hwDstSrcBlend
|= S_SBLEND_INV_DST_COLOR
;
161 case GL_SRC_ALPHA_SATURATE
:
162 current
->hwDstSrcBlend
|= S_SBLEND_SRC_ALPHA_SAT
;
166 if (current
->hwDstSrcBlend
!= prev
->hwDstSrcBlend
) {
167 prev
->hwDstSrcBlend
= current
->hwDstSrcBlend
;
168 smesa
->GlobalFlag
|= GFLAG_DSTBLEND
;
172 /* =============================================================
177 sis6326DDDepthFunc( GLcontext
*ctx
, GLenum func
)
179 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
180 __GLSiSHardware
*prev
= &smesa
->prev
;
181 __GLSiSHardware
*current
= &smesa
->current
;
183 current
->hwZ
&= ~MASK_6326_ZTestMode
;
187 current
->hwZ
|= S_ZSET_PASS_LESS
;
190 current
->hwZ
|= S_ZSET_PASS_GEQUAL
;
193 current
->hwZ
|= S_ZSET_PASS_LEQUAL
;
196 current
->hwZ
|= S_ZSET_PASS_GREATER
;
199 current
->hwZ
|= S_ZSET_PASS_NOTEQUAL
;
202 current
->hwZ
|= S_ZSET_PASS_EQUAL
;
205 current
->hwZ
|= S_ZSET_PASS_ALWAYS
;
208 current
->hwZ
|= S_ZSET_PASS_NEVER
;
212 if (current
->hwZ
!= prev
->hwZ
) {
213 prev
->hwZ
= current
->hwZ
;
214 smesa
->GlobalFlag
|= GFLAG_ZSETTING
;
219 sis6326DDDepthMask( GLcontext
*ctx
, GLboolean flag
)
221 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
222 __GLSiSHardware
*current
= &smesa
->current
;
225 current
->hwCapEnable
|= S_ENABLE_ZWrite
;
227 current
->hwCapEnable
&= ~S_ENABLE_ZWrite
;
230 /* =============================================================
235 sis6326DDFogfv( GLcontext
*ctx
, GLenum pname
, const GLfloat
*params
)
237 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
238 __GLSiSHardware
*current
= &smesa
->current
;
239 __GLSiSHardware
*prev
= &smesa
->prev
;
246 fogColor
= FLOAT_TO_UBYTE( ctx
->Fog
.Color
[0] ) << 16;
247 fogColor
|= FLOAT_TO_UBYTE( ctx
->Fog
.Color
[1] ) << 8;
248 fogColor
|= FLOAT_TO_UBYTE( ctx
->Fog
.Color
[2] );
249 current
->hwFog
= 0x01000000 | fogColor
;
250 if (current
->hwFog
!= prev
->hwFog
) {
251 prev
->hwFog
= current
->hwFog
;
252 smesa
->GlobalFlag
|= GFLAG_FOGSETTING
;
258 /* =============================================================
263 sis6326UpdateClipping(GLcontext
*ctx
)
265 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
267 __GLSiSHardware
*prev
= &smesa
->prev
;
268 __GLSiSHardware
*current
= &smesa
->current
;
270 GLint x1
, y1
, x2
, y2
;
274 x2
= smesa
->width
- 1;
275 y2
= smesa
->height
- 1;
277 if (ctx
->Scissor
.Enabled
) {
278 if (ctx
->Scissor
.X
> x1
)
280 if (ctx
->Scissor
.Y
> y1
)
282 if (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1 < x2
)
283 x2
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
284 if (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
- 1 < y2
)
285 y2
= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
- 1;
291 /*current->clipTopBottom = (y2 << 13) | y1;
292 current->clipLeftRight = (x1 << 13) | x2;*/ /* XXX */
293 current
->clipTopBottom
= (0 << 13) | smesa
->height
;
294 current
->clipLeftRight
= (0 << 13) | smesa
->width
;
296 if ((current
->clipTopBottom
!= prev
->clipTopBottom
) ||
297 (current
->clipLeftRight
!= prev
->clipLeftRight
)) {
298 prev
->clipTopBottom
= current
->clipTopBottom
;
299 prev
->clipLeftRight
= current
->clipLeftRight
;
300 smesa
->GlobalFlag
|= GFLAG_CLIPPING
;
305 sis6326DDScissor( GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
307 if (ctx
->Scissor
.Enabled
)
308 sis6326UpdateClipping( ctx
);
311 /* =============================================================
316 sis6326UpdateCull( GLcontext
*ctx
)
323 sis6326DDCullFace( GLcontext
*ctx
, GLenum mode
)
325 sis6326UpdateCull( ctx
);
329 sis6326DDFrontFace( GLcontext
*ctx
, GLenum mode
)
331 sis6326UpdateCull( ctx
);
334 /* =============================================================
338 static void sis6326DDColorMask( GLcontext
*ctx
,
339 GLboolean r
, GLboolean g
,
340 GLboolean b
, GLboolean a
)
342 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
344 if (r
&& g
&& b
&& ((ctx
->Visual
.alphaBits
== 0) || a
)) {
345 FALLBACK(smesa
, SIS_FALLBACK_WRITEMASK
, 0);
347 FALLBACK(smesa
, SIS_FALLBACK_WRITEMASK
, 1);
351 /* =============================================================
352 * Rendering attributes
355 static void sis6326UpdateSpecular(GLcontext
*ctx
)
357 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
358 __GLSiSHardware
*current
= &smesa
->current
;
360 if (NEED_SECONDARY_COLOR(ctx
))
361 current
->hwCapEnable
|= S_ENABLE_Specular
;
363 current
->hwCapEnable
&= ~S_ENABLE_Specular
;
366 static void sis6326DDLightModelfv(GLcontext
*ctx
, GLenum pname
,
367 const GLfloat
*param
)
369 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
370 sis6326UpdateSpecular(ctx
);
373 static void sis6326DDShadeModel( GLcontext
*ctx
, GLenum mode
)
375 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
377 /* Signal to sisRasterPrimitive to recalculate dwPrimitiveSet */
378 smesa
->hw_primitive
= -1;
381 /* =============================================================
385 /* =============================================================
389 static void sis6326CalcViewport( GLcontext
*ctx
)
391 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
392 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
393 GLfloat
*m
= smesa
->hw_viewport
;
395 /* See also sis_translate_vertex.
397 m
[MAT_SX
] = v
[MAT_SX
];
398 m
[MAT_TX
] = v
[MAT_TX
] + SUBPIXEL_X
;
399 m
[MAT_SY
] = - v
[MAT_SY
];
400 m
[MAT_TY
] = - v
[MAT_TY
] + smesa
->driDrawable
->h
+ SUBPIXEL_Y
;
401 m
[MAT_SZ
] = v
[MAT_SZ
] * smesa
->depth_scale
;
402 m
[MAT_TZ
] = v
[MAT_TZ
] * smesa
->depth_scale
;
405 static void sis6326DDViewport( GLcontext
*ctx
,
407 GLsizei width
, GLsizei height
)
409 sis6326CalcViewport( ctx
);
412 static void sis6326DDDepthRange( GLcontext
*ctx
,
413 GLclampd nearval
, GLclampd farval
)
415 sis6326CalcViewport( ctx
);
418 /* =============================================================
423 sis6326DDLogicOpCode( GLcontext
*ctx
, GLenum opcode
)
425 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
427 __GLSiSHardware
*prev
= &smesa
->prev
;
428 __GLSiSHardware
*current
= &smesa
->current
;
430 if (!ctx
->Color
.ColorLogicOpEnabled
)
433 current
->hwDstSet
&= ~MASK_ROP2
;
437 current
->hwDstSet
|= LOP_CLEAR
;
440 current
->hwDstSet
|= LOP_SET
;
443 current
->hwDstSet
|= LOP_COPY
;
445 case GL_COPY_INVERTED
:
446 current
->hwDstSet
|= LOP_COPY_INVERTED
;
449 current
->hwDstSet
|= LOP_NOOP
;
452 current
->hwDstSet
|= LOP_INVERT
;
455 current
->hwDstSet
|= LOP_AND
;
458 current
->hwDstSet
|= LOP_NAND
;
461 current
->hwDstSet
|= LOP_OR
;
464 current
->hwDstSet
|= LOP_NOR
;
467 current
->hwDstSet
|= LOP_XOR
;
470 current
->hwDstSet
|= LOP_EQUIV
;
473 current
->hwDstSet
|= LOP_AND_REVERSE
;
475 case GL_AND_INVERTED
:
476 current
->hwDstSet
|= LOP_AND_INVERTED
;
479 current
->hwDstSet
|= LOP_OR_REVERSE
;
482 current
->hwDstSet
|= LOP_OR_INVERTED
;
486 if (current
->hwDstSet
!= prev
->hwDstSet
) {
487 prev
->hwDstSet
= current
->hwDstSet
;
488 smesa
->GlobalFlag
|= GFLAG_DESTSETTING
;
492 void sis6326DDDrawBuffer( GLcontext
*ctx
, GLenum mode
)
494 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
496 __GLSiSHardware
*prev
= &smesa
->prev
;
497 __GLSiSHardware
*current
= &smesa
->current
;
499 if(getenv("SIS_DRAW_FRONT"))
500 ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] = BUFFER_FRONT_LEFT
;
502 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
> 1) {
503 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
507 current
->hwDstSet
&= ~MASK_DstBufferPitch
;
509 switch ( ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] ) {
510 case BUFFER_FRONT_LEFT
:
511 current
->hwOffsetDest
= smesa
->front
.offset
;
512 current
->hwDstSet
|= smesa
->front
.pitch
;
513 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
515 case BUFFER_BACK_LEFT
:
516 current
->hwOffsetDest
= smesa
->back
.offset
;
517 current
->hwDstSet
|= smesa
->back
.pitch
;
518 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
521 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
525 if (current
->hwDstSet
!= prev
->hwDstSet
) {
526 prev
->hwDstSet
= current
->hwDstSet
;
527 smesa
->GlobalFlag
|= GFLAG_DESTSETTING
;
530 if (current
->hwOffsetDest
!= prev
->hwOffsetDest
) {
531 prev
->hwOffsetDest
= current
->hwOffsetDest
;
532 smesa
->GlobalFlag
|= GFLAG_DESTSETTING
;
536 /* =============================================================
540 /* =============================================================
544 /* =============================================================
545 * State enable/disable
549 sis6326DDEnable( GLcontext
*ctx
, GLenum cap
, GLboolean state
)
551 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
553 __GLSiSHardware
*current
= &smesa
->current
;
559 current
->hwCapEnable
|= S_ENABLE_AlphaTest
;
561 current
->hwCapEnable
&= ~S_ENABLE_AlphaTest
;
566 /* if (state & !ctx->Color.ColorLogicOpEnabled) */
567 current
->hwCapEnable
|= S_ENABLE_Blend
;
569 current
->hwCapEnable
&= ~S_ENABLE_Blend
;
575 if (state
&& smesa
->depth
.offset
!= 0)
576 current
->hwCapEnable
|= S_ENABLE_ZTest
;
578 current
->hwCapEnable
&= ~S_ENABLE_ZTest
;
579 sis6326DDDepthMask( ctx
, ctx
->Depth
.Mask
);
583 current
->hwCapEnable
|= S_ENABLE_Dither
;
585 current
->hwCapEnable
&= ~S_ENABLE_Dither
;
589 current
->hwCapEnable
|= S_ENABLE_Fog
;
591 current
->hwCapEnable
&= ~S_ENABLE_Fog
;
593 case GL_COLOR_LOGIC_OP
:
595 sis6326DDLogicOpCode( ctx
, ctx
->Color
.LogicOp
);
597 sis6326DDLogicOpCode( ctx
, GL_COPY
);
599 case GL_SCISSOR_TEST
:
600 sis6326UpdateClipping( ctx
);
602 case GL_STENCIL_TEST
:
604 FALLBACK(smesa
, SIS_FALLBACK_STENCIL
, 1);
606 FALLBACK(smesa
, SIS_FALLBACK_STENCIL
, 0);
610 case GL_COLOR_SUM_EXT
:
611 sis6326UpdateSpecular(ctx
);
616 /* =============================================================
617 * State initialization, management
620 /* Called before beginning of rendering. */
622 sis6326UpdateHWState( GLcontext
*ctx
)
624 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
625 __GLSiSHardware
*prev
= &smesa
->prev
;
626 __GLSiSHardware
*current
= &smesa
->current
;
628 if (smesa
->NewGLState
& _NEW_TEXTURE
)
629 sisUpdateTextureState( ctx
);
631 if (current
->hwCapEnable
^ prev
->hwCapEnable
) {
632 prev
->hwCapEnable
= current
->hwCapEnable
;
633 smesa
->GlobalFlag
|= GFLAG_ENABLESETTING
;
636 if (smesa
->GlobalFlag
& GFLAG_RENDER_STATES
)
637 sis_update_render_state( smesa
);
639 if (smesa
->GlobalFlag
& GFLAG_TEXTURE_STATES
)
640 sis_update_texture_state( smesa
);
644 sis6326DDInvalidateState( GLcontext
*ctx
, GLuint new_state
)
646 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
648 _swrast_InvalidateState( ctx
, new_state
);
649 _swsetup_InvalidateState( ctx
, new_state
);
650 _vbo_InvalidateState( ctx
, new_state
);
651 _tnl_InvalidateState( ctx
, new_state
);
652 smesa
->NewGLState
|= new_state
;
655 /* Initialize the context's hardware state.
657 void sis6326DDInitState( sisContextPtr smesa
)
659 __GLSiSHardware
*prev
= &smesa
->prev
;
660 __GLSiSHardware
*current
= &smesa
->current
;
661 GLcontext
*ctx
= smesa
->glCtx
;
663 /* add Texture Perspective Enable */
664 current
->hwCapEnable
= S_ENABLE_TextureCache
|
665 S_ENABLE_TexturePerspective
| S_ENABLE_Dither
;
667 /* Z test mode is LESS */
668 current
->hwZ
= S_ZSET_PASS_LESS
| S_ZSET_FORMAT_16
;
669 if (ctx
->Visual
.depthBits
> 0)
670 current
->hwCapEnable
|= S_ENABLE_ZWrite
;
672 /* Alpha test mode is ALWAYS, alpha ref value is 0 */
673 current
->hwAlpha
= S_ASET_PASS_ALWAYS
;
675 /* ROP2 is COPYPEN */
676 current
->hwDstSet
= LOP_COPY
;
678 /* LinePattern is 0, Repeat Factor is 0 */
679 current
->hwLinePattern
= 0x00008000;
681 /* Src blend is BLEND_ONE, Dst blend is D3DBLEND_ZERO */
682 current
->hwDstSrcBlend
= S_SBLEND_ONE
| S_DBLEND_ZERO
;
684 switch (smesa
->bytesPerPixel
)
687 current
->hwDstSet
|= DST_FORMAT_RGB_565
;
690 current
->hwDstSet
|= DST_FORMAT_ARGB_8888
;
694 smesa
->depth_scale
= 1.0 / (GLfloat
)0xffff;
696 smesa
->clearTexCache
= GL_TRUE
;
698 smesa
->clearColorPattern
= 0;
700 sis6326UpdateZPattern(smesa
, 1.0);
701 sis6326UpdateCull(ctx
);
703 /* Set initial fog settings. Start and end are the same case. */
704 sis6326DDFogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
705 sis6326DDFogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
706 sis6326DDFogfv( ctx
, GL_FOG_MODE
, NULL
);
708 memcpy(prev
, current
, sizeof(__GLSiSHardware
));
711 /* Initialize the driver's state functions.
713 void sis6326DDInitStateFuncs( GLcontext
*ctx
)
715 ctx
->Driver
.UpdateState
= sis6326DDInvalidateState
;
717 ctx
->Driver
.Clear
= sis6326DDClear
;
718 ctx
->Driver
.ClearColor
= sis6326DDClearColor
;
719 ctx
->Driver
.ClearDepth
= sis6326DDClearDepth
;
721 ctx
->Driver
.AlphaFunc
= sis6326DDAlphaFunc
;
722 ctx
->Driver
.BlendFuncSeparate
= sis6326DDBlendFuncSeparate
;
723 ctx
->Driver
.ColorMask
= sis6326DDColorMask
;
724 ctx
->Driver
.CullFace
= sis6326DDCullFace
;
725 ctx
->Driver
.DepthMask
= sis6326DDDepthMask
;
726 ctx
->Driver
.DepthFunc
= sis6326DDDepthFunc
;
727 ctx
->Driver
.DepthRange
= sis6326DDDepthRange
;
728 ctx
->Driver
.DrawBuffer
= sis6326DDDrawBuffer
;
729 ctx
->Driver
.Enable
= sis6326DDEnable
;
730 ctx
->Driver
.FrontFace
= sis6326DDFrontFace
;
731 ctx
->Driver
.Fogfv
= sis6326DDFogfv
;
732 ctx
->Driver
.LogicOpcode
= sis6326DDLogicOpCode
;
733 ctx
->Driver
.Scissor
= sis6326DDScissor
;
734 ctx
->Driver
.ShadeModel
= sis6326DDShadeModel
;
735 ctx
->Driver
.LightModelfv
= sis6326DDLightModelfv
;
736 ctx
->Driver
.Viewport
= sis6326DDViewport
;