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"
36 #include "main/context.h"
37 #include "main/colormac.h"
38 #include "swrast/swrast.h"
41 #include "swrast_setup/swrast_setup.h"
44 /* =============================================================
49 sis6326DDAlphaFunc( struct gl_context
*ctx
, GLenum func
, GLfloat ref
)
51 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
54 __GLSiSHardware
*prev
= &smesa
->prev
;
55 __GLSiSHardware
*current
= &smesa
->current
;
57 CLAMPED_FLOAT_TO_UBYTE(refbyte
, ref
);
58 current
->hwAlpha
= refbyte
<< 16;
60 /* Alpha Test function */
64 current
->hwAlpha
|= S_ASET_PASS_NEVER
;
67 current
->hwAlpha
|= S_ASET_PASS_LESS
;
70 current
->hwAlpha
|= S_ASET_PASS_EQUAL
;
73 current
->hwAlpha
|= S_ASET_PASS_LEQUAL
;
76 current
->hwAlpha
|= S_ASET_PASS_GREATER
;
79 current
->hwAlpha
|= S_ASET_PASS_NOTEQUAL
;
82 current
->hwAlpha
|= S_ASET_PASS_GEQUAL
;
85 current
->hwAlpha
|= S_ASET_PASS_ALWAYS
;
89 prev
->hwAlpha
= current
->hwAlpha
;
90 smesa
->GlobalFlag
|= GFLAG_ALPHASETTING
;
94 sis6326DDBlendFuncSeparate( struct gl_context
*ctx
,
95 GLenum sfactorRGB
, GLenum dfactorRGB
,
96 GLenum sfactorA
, GLenum dfactorA
)
98 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
100 __GLSiSHardware
*prev
= &smesa
->prev
;
101 __GLSiSHardware
*current
= &smesa
->current
;
103 current
->hwDstSrcBlend
= 0;
108 current
->hwDstSrcBlend
|= S_DBLEND_ZERO
;
111 current
->hwDstSrcBlend
|= S_DBLEND_ONE
;
114 current
->hwDstSrcBlend
|= S_DBLEND_SRC_COLOR
;
116 case GL_ONE_MINUS_SRC_COLOR
:
117 current
->hwDstSrcBlend
|= S_DBLEND_INV_SRC_COLOR
;
120 current
->hwDstSrcBlend
|= S_DBLEND_SRC_ALPHA
;
122 case GL_ONE_MINUS_SRC_ALPHA
:
123 current
->hwDstSrcBlend
|= S_DBLEND_INV_SRC_ALPHA
;
126 current
->hwDstSrcBlend
|= S_DBLEND_DST_ALPHA
;
128 case GL_ONE_MINUS_DST_ALPHA
:
129 current
->hwDstSrcBlend
|= S_DBLEND_INV_DST_ALPHA
;
136 current
->hwDstSrcBlend
|= S_SBLEND_ZERO
;
139 current
->hwDstSrcBlend
|= S_SBLEND_ONE
;
142 current
->hwDstSrcBlend
|= S_SBLEND_SRC_ALPHA
;
144 case GL_ONE_MINUS_SRC_ALPHA
:
145 current
->hwDstSrcBlend
|= S_SBLEND_INV_SRC_ALPHA
;
148 current
->hwDstSrcBlend
|= S_SBLEND_DST_ALPHA
;
150 case GL_ONE_MINUS_DST_ALPHA
:
151 current
->hwDstSrcBlend
|= S_SBLEND_INV_DST_ALPHA
;
154 current
->hwDstSrcBlend
|= S_SBLEND_DST_COLOR
;
156 case GL_ONE_MINUS_DST_COLOR
:
157 current
->hwDstSrcBlend
|= S_SBLEND_INV_DST_COLOR
;
159 case GL_SRC_ALPHA_SATURATE
:
160 current
->hwDstSrcBlend
|= S_SBLEND_SRC_ALPHA_SAT
;
164 if (current
->hwDstSrcBlend
!= prev
->hwDstSrcBlend
) {
165 prev
->hwDstSrcBlend
= current
->hwDstSrcBlend
;
166 smesa
->GlobalFlag
|= GFLAG_DSTBLEND
;
170 /* =============================================================
175 sis6326DDDepthFunc( struct gl_context
*ctx
, GLenum func
)
177 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
178 __GLSiSHardware
*prev
= &smesa
->prev
;
179 __GLSiSHardware
*current
= &smesa
->current
;
181 current
->hwZ
&= ~MASK_6326_ZTestMode
;
185 current
->hwZ
|= S_ZSET_PASS_LESS
;
188 current
->hwZ
|= S_ZSET_PASS_GEQUAL
;
191 current
->hwZ
|= S_ZSET_PASS_LEQUAL
;
194 current
->hwZ
|= S_ZSET_PASS_GREATER
;
197 current
->hwZ
|= S_ZSET_PASS_NOTEQUAL
;
200 current
->hwZ
|= S_ZSET_PASS_EQUAL
;
203 current
->hwZ
|= S_ZSET_PASS_ALWAYS
;
206 current
->hwZ
|= S_ZSET_PASS_NEVER
;
210 if (current
->hwZ
!= prev
->hwZ
) {
211 prev
->hwZ
= current
->hwZ
;
212 smesa
->GlobalFlag
|= GFLAG_ZSETTING
;
217 sis6326DDDepthMask( struct gl_context
*ctx
, GLboolean flag
)
219 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
220 __GLSiSHardware
*current
= &smesa
->current
;
223 current
->hwCapEnable
|= S_ENABLE_ZWrite
;
225 current
->hwCapEnable
&= ~S_ENABLE_ZWrite
;
228 /* =============================================================
233 sis6326DDFogfv( struct gl_context
*ctx
, GLenum pname
, const GLfloat
*params
)
235 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
236 __GLSiSHardware
*current
= &smesa
->current
;
237 __GLSiSHardware
*prev
= &smesa
->prev
;
244 fogColor
= FLOAT_TO_UBYTE( ctx
->Fog
.Color
[0] ) << 16;
245 fogColor
|= FLOAT_TO_UBYTE( ctx
->Fog
.Color
[1] ) << 8;
246 fogColor
|= FLOAT_TO_UBYTE( ctx
->Fog
.Color
[2] );
247 current
->hwFog
= 0x01000000 | fogColor
;
248 if (current
->hwFog
!= prev
->hwFog
) {
249 prev
->hwFog
= current
->hwFog
;
250 smesa
->GlobalFlag
|= GFLAG_FOGSETTING
;
256 /* =============================================================
261 sis6326UpdateClipping(struct gl_context
*ctx
)
263 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
265 __GLSiSHardware
*prev
= &smesa
->prev
;
266 __GLSiSHardware
*current
= &smesa
->current
;
268 GLint x1
, y1
, x2
, y2
;
272 x2
= smesa
->width
- 1;
273 y2
= smesa
->height
- 1;
275 if (ctx
->Scissor
.Enabled
) {
276 if (ctx
->Scissor
.X
> x1
)
278 if (ctx
->Scissor
.Y
> y1
)
280 if (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1 < x2
)
281 x2
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
282 if (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
- 1 < y2
)
283 y2
= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
- 1;
289 /*current->clipTopBottom = (y2 << 13) | y1;
290 current->clipLeftRight = (x1 << 13) | x2;*/ /* XXX */
291 current
->clipTopBottom
= (0 << 13) | smesa
->height
;
292 current
->clipLeftRight
= (0 << 13) | smesa
->width
;
294 if ((current
->clipTopBottom
!= prev
->clipTopBottom
) ||
295 (current
->clipLeftRight
!= prev
->clipLeftRight
)) {
296 prev
->clipTopBottom
= current
->clipTopBottom
;
297 prev
->clipLeftRight
= current
->clipLeftRight
;
298 smesa
->GlobalFlag
|= GFLAG_CLIPPING
;
303 sis6326DDScissor( struct gl_context
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
305 if (ctx
->Scissor
.Enabled
)
306 sis6326UpdateClipping( ctx
);
309 /* =============================================================
314 sis6326UpdateCull( struct gl_context
*ctx
)
321 sis6326DDCullFace( struct gl_context
*ctx
, GLenum mode
)
323 sis6326UpdateCull( ctx
);
327 sis6326DDFrontFace( struct gl_context
*ctx
, GLenum mode
)
329 sis6326UpdateCull( ctx
);
332 /* =============================================================
336 static void sis6326DDColorMask( struct gl_context
*ctx
,
337 GLboolean r
, GLboolean g
,
338 GLboolean b
, GLboolean a
)
340 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
342 if (r
&& g
&& b
&& ((ctx
->Visual
.alphaBits
== 0) || a
)) {
343 FALLBACK(smesa
, SIS_FALLBACK_WRITEMASK
, 0);
345 FALLBACK(smesa
, SIS_FALLBACK_WRITEMASK
, 1);
349 /* =============================================================
350 * Rendering attributes
353 static void sis6326UpdateSpecular(struct gl_context
*ctx
)
355 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
356 __GLSiSHardware
*current
= &smesa
->current
;
358 if (NEED_SECONDARY_COLOR(ctx
))
359 current
->hwCapEnable
|= S_ENABLE_Specular
;
361 current
->hwCapEnable
&= ~S_ENABLE_Specular
;
364 static void sis6326DDLightModelfv(struct gl_context
*ctx
, GLenum pname
,
365 const GLfloat
*param
)
367 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
368 sis6326UpdateSpecular(ctx
);
371 static void sis6326DDShadeModel( struct gl_context
*ctx
, GLenum mode
)
373 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
375 /* Signal to sisRasterPrimitive to recalculate dwPrimitiveSet */
376 smesa
->hw_primitive
= -1;
379 /* =============================================================
383 /* =============================================================
387 static void sis6326CalcViewport( struct gl_context
*ctx
)
389 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
390 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
391 GLfloat
*m
= smesa
->hw_viewport
;
393 /* See also sis_translate_vertex.
395 m
[MAT_SX
] = v
[MAT_SX
];
396 m
[MAT_TX
] = v
[MAT_TX
] + SUBPIXEL_X
;
397 m
[MAT_SY
] = - v
[MAT_SY
];
398 m
[MAT_TY
] = - v
[MAT_TY
] + smesa
->driDrawable
->h
+ SUBPIXEL_Y
;
399 m
[MAT_SZ
] = v
[MAT_SZ
] * smesa
->depth_scale
;
400 m
[MAT_TZ
] = v
[MAT_TZ
] * smesa
->depth_scale
;
403 static void sis6326DDViewport( struct gl_context
*ctx
,
405 GLsizei width
, GLsizei height
)
407 sis6326CalcViewport( ctx
);
410 static void sis6326DDDepthRange( struct gl_context
*ctx
,
411 GLclampd nearval
, GLclampd farval
)
413 sis6326CalcViewport( ctx
);
416 /* =============================================================
421 sis6326DDLogicOpCode( struct gl_context
*ctx
, GLenum opcode
)
423 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
425 __GLSiSHardware
*prev
= &smesa
->prev
;
426 __GLSiSHardware
*current
= &smesa
->current
;
428 if (!ctx
->Color
.ColorLogicOpEnabled
)
431 current
->hwDstSet
&= ~MASK_ROP2
;
435 current
->hwDstSet
|= LOP_CLEAR
;
438 current
->hwDstSet
|= LOP_SET
;
441 current
->hwDstSet
|= LOP_COPY
;
443 case GL_COPY_INVERTED
:
444 current
->hwDstSet
|= LOP_COPY_INVERTED
;
447 current
->hwDstSet
|= LOP_NOOP
;
450 current
->hwDstSet
|= LOP_INVERT
;
453 current
->hwDstSet
|= LOP_AND
;
456 current
->hwDstSet
|= LOP_NAND
;
459 current
->hwDstSet
|= LOP_OR
;
462 current
->hwDstSet
|= LOP_NOR
;
465 current
->hwDstSet
|= LOP_XOR
;
468 current
->hwDstSet
|= LOP_EQUIV
;
471 current
->hwDstSet
|= LOP_AND_REVERSE
;
473 case GL_AND_INVERTED
:
474 current
->hwDstSet
|= LOP_AND_INVERTED
;
477 current
->hwDstSet
|= LOP_OR_REVERSE
;
480 current
->hwDstSet
|= LOP_OR_INVERTED
;
484 if (current
->hwDstSet
!= prev
->hwDstSet
) {
485 prev
->hwDstSet
= current
->hwDstSet
;
486 smesa
->GlobalFlag
|= GFLAG_DESTSETTING
;
490 void sis6326DDDrawBuffer( struct gl_context
*ctx
, GLenum mode
)
492 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
494 __GLSiSHardware
*prev
= &smesa
->prev
;
495 __GLSiSHardware
*current
= &smesa
->current
;
497 if(getenv("SIS_DRAW_FRONT"))
498 ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] = BUFFER_FRONT_LEFT
;
500 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
> 1) {
501 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
505 current
->hwDstSet
&= ~MASK_DstBufferPitch
;
507 switch ( ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] ) {
508 case BUFFER_FRONT_LEFT
:
509 current
->hwOffsetDest
= smesa
->front
.offset
;
510 current
->hwDstSet
|= smesa
->front
.pitch
;
511 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
513 case BUFFER_BACK_LEFT
:
514 current
->hwOffsetDest
= smesa
->back
.offset
;
515 current
->hwDstSet
|= smesa
->back
.pitch
;
516 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
519 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
523 if (current
->hwDstSet
!= prev
->hwDstSet
) {
524 prev
->hwDstSet
= current
->hwDstSet
;
525 smesa
->GlobalFlag
|= GFLAG_DESTSETTING
;
528 if (current
->hwOffsetDest
!= prev
->hwOffsetDest
) {
529 prev
->hwOffsetDest
= current
->hwOffsetDest
;
530 smesa
->GlobalFlag
|= GFLAG_DESTSETTING
;
534 /* =============================================================
538 /* =============================================================
542 /* =============================================================
543 * State enable/disable
547 sis6326DDEnable( struct gl_context
*ctx
, GLenum cap
, GLboolean state
)
549 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
551 __GLSiSHardware
*current
= &smesa
->current
;
557 current
->hwCapEnable
|= S_ENABLE_AlphaTest
;
559 current
->hwCapEnable
&= ~S_ENABLE_AlphaTest
;
564 /* if (state & !ctx->Color.ColorLogicOpEnabled) */
565 current
->hwCapEnable
|= S_ENABLE_Blend
;
567 current
->hwCapEnable
&= ~S_ENABLE_Blend
;
573 if (state
&& smesa
->depth
.offset
!= 0)
574 current
->hwCapEnable
|= S_ENABLE_ZTest
;
576 current
->hwCapEnable
&= ~S_ENABLE_ZTest
;
577 sis6326DDDepthMask( ctx
, ctx
->Depth
.Mask
);
581 current
->hwCapEnable
|= S_ENABLE_Dither
;
583 current
->hwCapEnable
&= ~S_ENABLE_Dither
;
587 current
->hwCapEnable
|= S_ENABLE_Fog
;
589 current
->hwCapEnable
&= ~S_ENABLE_Fog
;
591 case GL_COLOR_LOGIC_OP
:
593 sis6326DDLogicOpCode( ctx
, ctx
->Color
.LogicOp
);
595 sis6326DDLogicOpCode( ctx
, GL_COPY
);
597 case GL_SCISSOR_TEST
:
598 sis6326UpdateClipping( ctx
);
600 case GL_STENCIL_TEST
:
602 FALLBACK(smesa
, SIS_FALLBACK_STENCIL
, 1);
604 FALLBACK(smesa
, SIS_FALLBACK_STENCIL
, 0);
608 case GL_COLOR_SUM_EXT
:
609 sis6326UpdateSpecular(ctx
);
614 /* =============================================================
615 * State initialization, management
618 /* Called before beginning of rendering. */
620 sis6326UpdateHWState( struct gl_context
*ctx
)
622 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
623 __GLSiSHardware
*prev
= &smesa
->prev
;
624 __GLSiSHardware
*current
= &smesa
->current
;
626 if (smesa
->NewGLState
& _NEW_TEXTURE
)
627 sisUpdateTextureState( ctx
);
629 if (current
->hwCapEnable
^ prev
->hwCapEnable
) {
630 prev
->hwCapEnable
= current
->hwCapEnable
;
631 smesa
->GlobalFlag
|= GFLAG_ENABLESETTING
;
634 if (smesa
->GlobalFlag
& GFLAG_RENDER_STATES
)
635 sis_update_render_state( smesa
);
637 if (smesa
->GlobalFlag
& GFLAG_TEXTURE_STATES
)
638 sis_update_texture_state( smesa
);
642 sis6326DDInvalidateState( struct gl_context
*ctx
, GLuint new_state
)
644 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
646 _swrast_InvalidateState( ctx
, new_state
);
647 _swsetup_InvalidateState( ctx
, new_state
);
648 _vbo_InvalidateState( ctx
, new_state
);
649 _tnl_InvalidateState( ctx
, new_state
);
650 smesa
->NewGLState
|= new_state
;
653 /* Initialize the context's hardware state.
655 void sis6326DDInitState( sisContextPtr smesa
)
657 __GLSiSHardware
*prev
= &smesa
->prev
;
658 __GLSiSHardware
*current
= &smesa
->current
;
659 struct gl_context
*ctx
= smesa
->glCtx
;
661 /* add Texture Perspective Enable */
662 current
->hwCapEnable
= S_ENABLE_TextureCache
|
663 S_ENABLE_TexturePerspective
| S_ENABLE_Dither
;
665 /* Z test mode is LESS */
666 current
->hwZ
= S_ZSET_PASS_LESS
| S_ZSET_FORMAT_16
;
667 if (ctx
->Visual
.depthBits
> 0)
668 current
->hwCapEnable
|= S_ENABLE_ZWrite
;
670 /* Alpha test mode is ALWAYS, alpha ref value is 0 */
671 current
->hwAlpha
= S_ASET_PASS_ALWAYS
;
673 /* ROP2 is COPYPEN */
674 current
->hwDstSet
= LOP_COPY
;
676 /* LinePattern is 0, Repeat Factor is 0 */
677 current
->hwLinePattern
= 0x00008000;
679 /* Src blend is BLEND_ONE, Dst blend is D3DBLEND_ZERO */
680 current
->hwDstSrcBlend
= S_SBLEND_ONE
| S_DBLEND_ZERO
;
682 switch (smesa
->bytesPerPixel
)
685 current
->hwDstSet
|= DST_FORMAT_RGB_565
;
688 current
->hwDstSet
|= DST_FORMAT_ARGB_8888
;
692 smesa
->depth_scale
= 1.0 / (GLfloat
)0xffff;
694 smesa
->clearTexCache
= GL_TRUE
;
696 smesa
->clearColorPattern
= 0;
698 sis6326UpdateZPattern(smesa
, 1.0);
699 sis6326UpdateCull(ctx
);
701 /* Set initial fog settings. Start and end are the same case. */
702 sis6326DDFogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
703 sis6326DDFogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
704 sis6326DDFogfv( ctx
, GL_FOG_MODE
, NULL
);
706 memcpy(prev
, current
, sizeof(__GLSiSHardware
));
709 /* Initialize the driver's state functions.
711 void sis6326DDInitStateFuncs( struct gl_context
*ctx
)
713 ctx
->Driver
.UpdateState
= sis6326DDInvalidateState
;
715 ctx
->Driver
.Clear
= sis6326DDClear
;
716 ctx
->Driver
.ClearColor
= sis6326DDClearColor
;
717 ctx
->Driver
.ClearDepth
= sis6326DDClearDepth
;
719 ctx
->Driver
.AlphaFunc
= sis6326DDAlphaFunc
;
720 ctx
->Driver
.BlendFuncSeparate
= sis6326DDBlendFuncSeparate
;
721 ctx
->Driver
.ColorMask
= sis6326DDColorMask
;
722 ctx
->Driver
.CullFace
= sis6326DDCullFace
;
723 ctx
->Driver
.DepthMask
= sis6326DDDepthMask
;
724 ctx
->Driver
.DepthFunc
= sis6326DDDepthFunc
;
725 ctx
->Driver
.DepthRange
= sis6326DDDepthRange
;
726 ctx
->Driver
.DrawBuffer
= sis6326DDDrawBuffer
;
727 ctx
->Driver
.Enable
= sis6326DDEnable
;
728 ctx
->Driver
.FrontFace
= sis6326DDFrontFace
;
729 ctx
->Driver
.Fogfv
= sis6326DDFogfv
;
730 ctx
->Driver
.LogicOpcode
= sis6326DDLogicOpCode
;
731 ctx
->Driver
.Scissor
= sis6326DDScissor
;
732 ctx
->Driver
.ShadeModel
= sis6326DDShadeModel
;
733 ctx
->Driver
.LightModelfv
= sis6326DDLightModelfv
;
734 ctx
->Driver
.Viewport
= sis6326DDViewport
;