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;