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 "main/state.h"
39 #include "swrast/swrast.h"
42 #include "swrast_setup/swrast_setup.h"
45 /* =============================================================
50 sis6326DDAlphaFunc( struct gl_context
*ctx
, GLenum func
, GLfloat ref
)
52 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
55 __GLSiSHardware
*prev
= &smesa
->prev
;
56 __GLSiSHardware
*current
= &smesa
->current
;
58 CLAMPED_FLOAT_TO_UBYTE(refbyte
, ref
);
59 current
->hwAlpha
= refbyte
<< 16;
61 /* Alpha Test function */
65 current
->hwAlpha
|= S_ASET_PASS_NEVER
;
68 current
->hwAlpha
|= S_ASET_PASS_LESS
;
71 current
->hwAlpha
|= S_ASET_PASS_EQUAL
;
74 current
->hwAlpha
|= S_ASET_PASS_LEQUAL
;
77 current
->hwAlpha
|= S_ASET_PASS_GREATER
;
80 current
->hwAlpha
|= S_ASET_PASS_NOTEQUAL
;
83 current
->hwAlpha
|= S_ASET_PASS_GEQUAL
;
86 current
->hwAlpha
|= S_ASET_PASS_ALWAYS
;
90 prev
->hwAlpha
= current
->hwAlpha
;
91 smesa
->GlobalFlag
|= GFLAG_ALPHASETTING
;
95 sis6326DDBlendFuncSeparate( struct gl_context
*ctx
,
96 GLenum sfactorRGB
, GLenum dfactorRGB
,
97 GLenum sfactorA
, GLenum dfactorA
)
99 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
101 __GLSiSHardware
*prev
= &smesa
->prev
;
102 __GLSiSHardware
*current
= &smesa
->current
;
104 current
->hwDstSrcBlend
= 0;
109 current
->hwDstSrcBlend
|= S_DBLEND_ZERO
;
112 current
->hwDstSrcBlend
|= S_DBLEND_ONE
;
115 current
->hwDstSrcBlend
|= S_DBLEND_SRC_COLOR
;
117 case GL_ONE_MINUS_SRC_COLOR
:
118 current
->hwDstSrcBlend
|= S_DBLEND_INV_SRC_COLOR
;
121 current
->hwDstSrcBlend
|= S_DBLEND_SRC_ALPHA
;
123 case GL_ONE_MINUS_SRC_ALPHA
:
124 current
->hwDstSrcBlend
|= S_DBLEND_INV_SRC_ALPHA
;
127 current
->hwDstSrcBlend
|= S_DBLEND_DST_ALPHA
;
129 case GL_ONE_MINUS_DST_ALPHA
:
130 current
->hwDstSrcBlend
|= S_DBLEND_INV_DST_ALPHA
;
137 current
->hwDstSrcBlend
|= S_SBLEND_ZERO
;
140 current
->hwDstSrcBlend
|= S_SBLEND_ONE
;
143 current
->hwDstSrcBlend
|= S_SBLEND_SRC_ALPHA
;
145 case GL_ONE_MINUS_SRC_ALPHA
:
146 current
->hwDstSrcBlend
|= S_SBLEND_INV_SRC_ALPHA
;
149 current
->hwDstSrcBlend
|= S_SBLEND_DST_ALPHA
;
151 case GL_ONE_MINUS_DST_ALPHA
:
152 current
->hwDstSrcBlend
|= S_SBLEND_INV_DST_ALPHA
;
155 current
->hwDstSrcBlend
|= S_SBLEND_DST_COLOR
;
157 case GL_ONE_MINUS_DST_COLOR
:
158 current
->hwDstSrcBlend
|= S_SBLEND_INV_DST_COLOR
;
160 case GL_SRC_ALPHA_SATURATE
:
161 current
->hwDstSrcBlend
|= S_SBLEND_SRC_ALPHA_SAT
;
165 if (current
->hwDstSrcBlend
!= prev
->hwDstSrcBlend
) {
166 prev
->hwDstSrcBlend
= current
->hwDstSrcBlend
;
167 smesa
->GlobalFlag
|= GFLAG_DSTBLEND
;
171 /* =============================================================
176 sis6326DDDepthFunc( struct gl_context
*ctx
, GLenum func
)
178 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
179 __GLSiSHardware
*prev
= &smesa
->prev
;
180 __GLSiSHardware
*current
= &smesa
->current
;
182 current
->hwZ
&= ~MASK_6326_ZTestMode
;
186 current
->hwZ
|= S_ZSET_PASS_LESS
;
189 current
->hwZ
|= S_ZSET_PASS_GEQUAL
;
192 current
->hwZ
|= S_ZSET_PASS_LEQUAL
;
195 current
->hwZ
|= S_ZSET_PASS_GREATER
;
198 current
->hwZ
|= S_ZSET_PASS_NOTEQUAL
;
201 current
->hwZ
|= S_ZSET_PASS_EQUAL
;
204 current
->hwZ
|= S_ZSET_PASS_ALWAYS
;
207 current
->hwZ
|= S_ZSET_PASS_NEVER
;
211 if (current
->hwZ
!= prev
->hwZ
) {
212 prev
->hwZ
= current
->hwZ
;
213 smesa
->GlobalFlag
|= GFLAG_ZSETTING
;
218 sis6326DDDepthMask( struct gl_context
*ctx
, GLboolean flag
)
220 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
221 __GLSiSHardware
*current
= &smesa
->current
;
224 current
->hwCapEnable
|= S_ENABLE_ZWrite
;
226 current
->hwCapEnable
&= ~S_ENABLE_ZWrite
;
229 /* =============================================================
234 sis6326DDFogfv( struct gl_context
*ctx
, GLenum pname
, const GLfloat
*params
)
236 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
237 __GLSiSHardware
*current
= &smesa
->current
;
238 __GLSiSHardware
*prev
= &smesa
->prev
;
245 fogColor
= FLOAT_TO_UBYTE( ctx
->Fog
.Color
[0] ) << 16;
246 fogColor
|= FLOAT_TO_UBYTE( ctx
->Fog
.Color
[1] ) << 8;
247 fogColor
|= FLOAT_TO_UBYTE( ctx
->Fog
.Color
[2] );
248 current
->hwFog
= 0x01000000 | fogColor
;
249 if (current
->hwFog
!= prev
->hwFog
) {
250 prev
->hwFog
= current
->hwFog
;
251 smesa
->GlobalFlag
|= GFLAG_FOGSETTING
;
257 /* =============================================================
262 sis6326UpdateClipping(struct gl_context
*ctx
)
264 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
266 __GLSiSHardware
*prev
= &smesa
->prev
;
267 __GLSiSHardware
*current
= &smesa
->current
;
269 GLint x1
, y1
, x2
, y2
;
273 x2
= smesa
->width
- 1;
274 y2
= smesa
->height
- 1;
276 if (ctx
->Scissor
.Enabled
) {
277 if (ctx
->Scissor
.X
> x1
)
279 if (ctx
->Scissor
.Y
> y1
)
281 if (ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1 < x2
)
282 x2
= ctx
->Scissor
.X
+ ctx
->Scissor
.Width
- 1;
283 if (ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
- 1 < y2
)
284 y2
= ctx
->Scissor
.Y
+ ctx
->Scissor
.Height
- 1;
290 /*current->clipTopBottom = (y2 << 13) | y1;
291 current->clipLeftRight = (x1 << 13) | x2;*/ /* XXX */
292 current
->clipTopBottom
= (0 << 13) | smesa
->height
;
293 current
->clipLeftRight
= (0 << 13) | smesa
->width
;
295 if ((current
->clipTopBottom
!= prev
->clipTopBottom
) ||
296 (current
->clipLeftRight
!= prev
->clipLeftRight
)) {
297 prev
->clipTopBottom
= current
->clipTopBottom
;
298 prev
->clipLeftRight
= current
->clipLeftRight
;
299 smesa
->GlobalFlag
|= GFLAG_CLIPPING
;
304 sis6326DDScissor( struct gl_context
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
306 if (ctx
->Scissor
.Enabled
)
307 sis6326UpdateClipping( ctx
);
310 /* =============================================================
315 sis6326UpdateCull( struct gl_context
*ctx
)
322 sis6326DDCullFace( struct gl_context
*ctx
, GLenum mode
)
324 sis6326UpdateCull( ctx
);
328 sis6326DDFrontFace( struct gl_context
*ctx
, GLenum mode
)
330 sis6326UpdateCull( ctx
);
333 /* =============================================================
337 static void sis6326DDColorMask( struct gl_context
*ctx
,
338 GLboolean r
, GLboolean g
,
339 GLboolean b
, GLboolean a
)
341 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
343 if (r
&& g
&& b
&& ((ctx
->Visual
.alphaBits
== 0) || a
)) {
344 FALLBACK(smesa
, SIS_FALLBACK_WRITEMASK
, 0);
346 FALLBACK(smesa
, SIS_FALLBACK_WRITEMASK
, 1);
350 /* =============================================================
351 * Rendering attributes
354 static void sis6326UpdateSpecular(struct gl_context
*ctx
)
356 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
357 __GLSiSHardware
*current
= &smesa
->current
;
359 if (_mesa_need_secondary_color(ctx
))
360 current
->hwCapEnable
|= S_ENABLE_Specular
;
362 current
->hwCapEnable
&= ~S_ENABLE_Specular
;
365 static void sis6326DDLightModelfv(struct gl_context
*ctx
, GLenum pname
,
366 const GLfloat
*param
)
368 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
369 sis6326UpdateSpecular(ctx
);
372 static void sis6326DDShadeModel( struct gl_context
*ctx
, GLenum mode
)
374 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
376 /* Signal to sisRasterPrimitive to recalculate dwPrimitiveSet */
377 smesa
->hw_primitive
= -1;
380 /* =============================================================
384 /* =============================================================
388 static void sis6326CalcViewport( struct gl_context
*ctx
)
390 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
391 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
392 GLfloat
*m
= smesa
->hw_viewport
;
394 /* See also sis_translate_vertex.
396 m
[MAT_SX
] = v
[MAT_SX
];
397 m
[MAT_TX
] = v
[MAT_TX
] + SUBPIXEL_X
;
398 m
[MAT_SY
] = - v
[MAT_SY
];
399 m
[MAT_TY
] = - v
[MAT_TY
] + smesa
->driDrawable
->h
+ SUBPIXEL_Y
;
400 m
[MAT_SZ
] = v
[MAT_SZ
] * smesa
->depth_scale
;
401 m
[MAT_TZ
] = v
[MAT_TZ
] * smesa
->depth_scale
;
404 static void sis6326DDViewport( struct gl_context
*ctx
,
406 GLsizei width
, GLsizei height
)
408 sis6326CalcViewport( ctx
);
411 static void sis6326DDDepthRange( struct gl_context
*ctx
,
412 GLclampd nearval
, GLclampd farval
)
414 sis6326CalcViewport( ctx
);
417 /* =============================================================
422 sis6326DDLogicOpCode( struct gl_context
*ctx
, GLenum opcode
)
424 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
426 __GLSiSHardware
*prev
= &smesa
->prev
;
427 __GLSiSHardware
*current
= &smesa
->current
;
429 if (!ctx
->Color
.ColorLogicOpEnabled
)
432 current
->hwDstSet
&= ~MASK_ROP2
;
436 current
->hwDstSet
|= LOP_CLEAR
;
439 current
->hwDstSet
|= LOP_SET
;
442 current
->hwDstSet
|= LOP_COPY
;
444 case GL_COPY_INVERTED
:
445 current
->hwDstSet
|= LOP_COPY_INVERTED
;
448 current
->hwDstSet
|= LOP_NOOP
;
451 current
->hwDstSet
|= LOP_INVERT
;
454 current
->hwDstSet
|= LOP_AND
;
457 current
->hwDstSet
|= LOP_NAND
;
460 current
->hwDstSet
|= LOP_OR
;
463 current
->hwDstSet
|= LOP_NOR
;
466 current
->hwDstSet
|= LOP_XOR
;
469 current
->hwDstSet
|= LOP_EQUIV
;
472 current
->hwDstSet
|= LOP_AND_REVERSE
;
474 case GL_AND_INVERTED
:
475 current
->hwDstSet
|= LOP_AND_INVERTED
;
478 current
->hwDstSet
|= LOP_OR_REVERSE
;
481 current
->hwDstSet
|= LOP_OR_INVERTED
;
485 if (current
->hwDstSet
!= prev
->hwDstSet
) {
486 prev
->hwDstSet
= current
->hwDstSet
;
487 smesa
->GlobalFlag
|= GFLAG_DESTSETTING
;
491 void sis6326DDDrawBuffer( struct gl_context
*ctx
, GLenum mode
)
493 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
495 __GLSiSHardware
*prev
= &smesa
->prev
;
496 __GLSiSHardware
*current
= &smesa
->current
;
498 if(getenv("SIS_DRAW_FRONT"))
499 ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] = BUFFER_FRONT_LEFT
;
501 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
> 1) {
502 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
506 current
->hwDstSet
&= ~MASK_DstBufferPitch
;
508 switch ( ctx
->DrawBuffer
->_ColorDrawBufferIndexes
[0] ) {
509 case BUFFER_FRONT_LEFT
:
510 current
->hwOffsetDest
= smesa
->front
.offset
;
511 current
->hwDstSet
|= smesa
->front
.pitch
;
512 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
514 case BUFFER_BACK_LEFT
:
515 current
->hwOffsetDest
= smesa
->back
.offset
;
516 current
->hwDstSet
|= smesa
->back
.pitch
;
517 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
520 FALLBACK( smesa
, SIS_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
524 if (current
->hwDstSet
!= prev
->hwDstSet
) {
525 prev
->hwDstSet
= current
->hwDstSet
;
526 smesa
->GlobalFlag
|= GFLAG_DESTSETTING
;
529 if (current
->hwOffsetDest
!= prev
->hwOffsetDest
) {
530 prev
->hwOffsetDest
= current
->hwOffsetDest
;
531 smesa
->GlobalFlag
|= GFLAG_DESTSETTING
;
535 /* =============================================================
539 /* =============================================================
543 /* =============================================================
544 * State enable/disable
548 sis6326DDEnable( struct gl_context
*ctx
, GLenum cap
, GLboolean state
)
550 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
552 __GLSiSHardware
*current
= &smesa
->current
;
558 current
->hwCapEnable
|= S_ENABLE_AlphaTest
;
560 current
->hwCapEnable
&= ~S_ENABLE_AlphaTest
;
565 /* if (state & !ctx->Color.ColorLogicOpEnabled) */
566 current
->hwCapEnable
|= S_ENABLE_Blend
;
568 current
->hwCapEnable
&= ~S_ENABLE_Blend
;
574 if (state
&& smesa
->depth
.offset
!= 0)
575 current
->hwCapEnable
|= S_ENABLE_ZTest
;
577 current
->hwCapEnable
&= ~S_ENABLE_ZTest
;
578 sis6326DDDepthMask( ctx
, ctx
->Depth
.Mask
);
582 current
->hwCapEnable
|= S_ENABLE_Dither
;
584 current
->hwCapEnable
&= ~S_ENABLE_Dither
;
588 current
->hwCapEnable
|= S_ENABLE_Fog
;
590 current
->hwCapEnable
&= ~S_ENABLE_Fog
;
592 case GL_COLOR_LOGIC_OP
:
594 sis6326DDLogicOpCode( ctx
, ctx
->Color
.LogicOp
);
596 sis6326DDLogicOpCode( ctx
, GL_COPY
);
598 case GL_SCISSOR_TEST
:
599 sis6326UpdateClipping( ctx
);
601 case GL_STENCIL_TEST
:
603 FALLBACK(smesa
, SIS_FALLBACK_STENCIL
, 1);
605 FALLBACK(smesa
, SIS_FALLBACK_STENCIL
, 0);
609 case GL_COLOR_SUM_EXT
:
610 sis6326UpdateSpecular(ctx
);
615 /* =============================================================
616 * State initialization, management
619 /* Called before beginning of rendering. */
621 sis6326UpdateHWState( struct gl_context
*ctx
)
623 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
624 __GLSiSHardware
*prev
= &smesa
->prev
;
625 __GLSiSHardware
*current
= &smesa
->current
;
627 if (smesa
->NewGLState
& _NEW_TEXTURE
)
628 sisUpdateTextureState( ctx
);
630 if (current
->hwCapEnable
^ prev
->hwCapEnable
) {
631 prev
->hwCapEnable
= current
->hwCapEnable
;
632 smesa
->GlobalFlag
|= GFLAG_ENABLESETTING
;
635 if (smesa
->GlobalFlag
& GFLAG_RENDER_STATES
)
636 sis_update_render_state( smesa
);
638 if (smesa
->GlobalFlag
& GFLAG_TEXTURE_STATES
)
639 sis_update_texture_state( smesa
);
643 sis6326DDInvalidateState( struct gl_context
*ctx
, GLuint new_state
)
645 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
647 _swrast_InvalidateState( ctx
, new_state
);
648 _swsetup_InvalidateState( ctx
, new_state
);
649 _vbo_InvalidateState( ctx
, new_state
);
650 _tnl_InvalidateState( ctx
, new_state
);
651 smesa
->NewGLState
|= new_state
;
654 /* Initialize the context's hardware state.
656 void sis6326DDInitState( sisContextPtr smesa
)
658 __GLSiSHardware
*prev
= &smesa
->prev
;
659 __GLSiSHardware
*current
= &smesa
->current
;
660 struct gl_context
*ctx
= smesa
->glCtx
;
662 /* add Texture Perspective Enable */
663 current
->hwCapEnable
= S_ENABLE_TextureCache
|
664 S_ENABLE_TexturePerspective
| S_ENABLE_Dither
;
666 /* Z test mode is LESS */
667 current
->hwZ
= S_ZSET_PASS_LESS
| S_ZSET_FORMAT_16
;
668 if (ctx
->Visual
.depthBits
> 0)
669 current
->hwCapEnable
|= S_ENABLE_ZWrite
;
671 /* Alpha test mode is ALWAYS, alpha ref value is 0 */
672 current
->hwAlpha
= S_ASET_PASS_ALWAYS
;
674 /* ROP2 is COPYPEN */
675 current
->hwDstSet
= LOP_COPY
;
677 /* LinePattern is 0, Repeat Factor is 0 */
678 current
->hwLinePattern
= 0x00008000;
680 /* Src blend is BLEND_ONE, Dst blend is D3DBLEND_ZERO */
681 current
->hwDstSrcBlend
= S_SBLEND_ONE
| S_DBLEND_ZERO
;
683 switch (smesa
->bytesPerPixel
)
686 current
->hwDstSet
|= DST_FORMAT_RGB_565
;
689 current
->hwDstSet
|= DST_FORMAT_ARGB_8888
;
693 smesa
->depth_scale
= 1.0 / (GLfloat
)0xffff;
695 smesa
->clearTexCache
= GL_TRUE
;
697 smesa
->clearColorPattern
= 0;
699 sis6326UpdateZPattern(smesa
, 1.0);
700 sis6326UpdateCull(ctx
);
702 /* Set initial fog settings. Start and end are the same case. */
703 sis6326DDFogfv( ctx
, GL_FOG_DENSITY
, &ctx
->Fog
.Density
);
704 sis6326DDFogfv( ctx
, GL_FOG_END
, &ctx
->Fog
.End
);
705 sis6326DDFogfv( ctx
, GL_FOG_MODE
, NULL
);
707 memcpy(prev
, current
, sizeof(__GLSiSHardware
));
710 /* Initialize the driver's state functions.
712 void sis6326DDInitStateFuncs( struct gl_context
*ctx
)
714 ctx
->Driver
.UpdateState
= sis6326DDInvalidateState
;
716 ctx
->Driver
.Clear
= sis6326DDClear
;
717 ctx
->Driver
.ClearColor
= sis6326DDClearColor
;
718 ctx
->Driver
.ClearDepth
= sis6326DDClearDepth
;
720 ctx
->Driver
.AlphaFunc
= sis6326DDAlphaFunc
;
721 ctx
->Driver
.BlendFuncSeparate
= sis6326DDBlendFuncSeparate
;
722 ctx
->Driver
.ColorMask
= sis6326DDColorMask
;
723 ctx
->Driver
.CullFace
= sis6326DDCullFace
;
724 ctx
->Driver
.DepthMask
= sis6326DDDepthMask
;
725 ctx
->Driver
.DepthFunc
= sis6326DDDepthFunc
;
726 ctx
->Driver
.DepthRange
= sis6326DDDepthRange
;
727 ctx
->Driver
.DrawBuffer
= sis6326DDDrawBuffer
;
728 ctx
->Driver
.Enable
= sis6326DDEnable
;
729 ctx
->Driver
.FrontFace
= sis6326DDFrontFace
;
730 ctx
->Driver
.Fogfv
= sis6326DDFogfv
;
731 ctx
->Driver
.LogicOpcode
= sis6326DDLogicOpCode
;
732 ctx
->Driver
.Scissor
= sis6326DDScissor
;
733 ctx
->Driver
.ShadeModel
= sis6326DDShadeModel
;
734 ctx
->Driver
.LightModelfv
= sis6326DDLightModelfv
;
735 ctx
->Driver
.Viewport
= sis6326DDViewport
;