📄 tdfx_state.c
字号:
/* -*- mode: c; c-basic-offset: 3 -*- * * Copyright 2000 VA Linux Systems Inc., Fremont, California. * * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. *//* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ *//* * New fixes: * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004 * * Original rewrite: * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000 * * Authors: * Gareth Hughes <gareth@valinux.com> * Brian Paul <brianp@valinux.com> * Keith Whitwell <keith@tungstengraphics.com> (port to 3.5) * */#include "mtypes.h"#include "colormac.h"#include "texformat.h"#include "texstore.h"#include "teximage.h"#include "swrast/swrast.h"#include "vbo/vbo.h"#include "tnl/tnl.h"#include "tnl/t_pipeline.h"#include "swrast_setup/swrast_setup.h"#include "tdfx_context.h"#include "tdfx_state.h"#include "tdfx_vb.h"#include "tdfx_tex.h"#include "tdfx_texman.h"#include "tdfx_texstate.h"#include "tdfx_tris.h"#include "tdfx_render.h"/* ============================================================= * Alpha blending */static void tdfxUpdateAlphaMode( GLcontext *ctx ){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); GrCmpFnc_t func; GrAlphaBlendFnc_t srcRGB, dstRGB, srcA, dstA; GrAlphaBlendOp_t eqRGB, eqA; GrAlpha_t ref = (GLint) (ctx->Color.AlphaRef * 255.0); GLboolean isNapalm = TDFX_IS_NAPALM(fxMesa); GLboolean have32bpp = (ctx->Visual.greenBits == 8); GLboolean haveAlpha = fxMesa->haveHwAlpha; if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s()\n", __FUNCTION__ ); } if ( ctx->Color.AlphaEnabled ) { func = ctx->Color.AlphaFunc - GL_NEVER + GR_CMP_NEVER; } else { func = GR_CMP_ALWAYS; } if ( ctx->Color.BlendEnabled && (fxMesa->Fallback & TDFX_FALLBACK_BLEND) == 0 ) { switch ( ctx->Color.BlendSrcRGB ) { case GL_ZERO: srcRGB = GR_BLEND_ZERO; break; case GL_ONE: srcRGB = GR_BLEND_ONE; break; case GL_DST_COLOR: srcRGB = GR_BLEND_DST_COLOR; break; case GL_ONE_MINUS_DST_COLOR: srcRGB = GR_BLEND_ONE_MINUS_DST_COLOR; break; case GL_SRC_ALPHA: srcRGB = GR_BLEND_SRC_ALPHA; break; case GL_ONE_MINUS_SRC_ALPHA: srcRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA; break; case GL_DST_ALPHA: srcRGB = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/; break; case GL_ONE_MINUS_DST_ALPHA: srcRGB = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; case GL_SRC_ALPHA_SATURATE: srcRGB = GR_BLEND_ALPHA_SATURATE; break; case GL_SRC_COLOR: if (isNapalm) { srcRGB = GR_BLEND_SAME_COLOR_EXT; break; } case GL_ONE_MINUS_SRC_COLOR: if (isNapalm) { srcRGB = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT; break; } default: srcRGB = GR_BLEND_ONE; } switch ( ctx->Color.BlendSrcA ) { case GL_ZERO: srcA = GR_BLEND_ZERO; break; case GL_ONE: srcA = GR_BLEND_ONE; break; case GL_SRC_COLOR: case GL_SRC_ALPHA: srcA = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*JJJ*/; break; case GL_ONE_MINUS_SRC_COLOR: case GL_ONE_MINUS_SRC_ALPHA: srcA = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*JJJ*/; break; case GL_DST_COLOR: case GL_DST_ALPHA: srcA = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/; break; case GL_ONE_MINUS_DST_COLOR: case GL_ONE_MINUS_DST_ALPHA: srcA = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; case GL_SRC_ALPHA_SATURATE: srcA = GR_BLEND_ONE; break; default: srcA = GR_BLEND_ONE; } switch ( ctx->Color.BlendDstRGB ) { case GL_ZERO: dstRGB = GR_BLEND_ZERO; break; case GL_ONE: dstRGB = GR_BLEND_ONE; break; case GL_SRC_COLOR: dstRGB = GR_BLEND_SRC_COLOR; break; case GL_ONE_MINUS_SRC_COLOR: dstRGB = GR_BLEND_ONE_MINUS_SRC_COLOR; break; case GL_SRC_ALPHA: dstRGB = GR_BLEND_SRC_ALPHA; break; case GL_ONE_MINUS_SRC_ALPHA: dstRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA; break; case GL_DST_ALPHA: dstRGB = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/; break; case GL_ONE_MINUS_DST_ALPHA: dstRGB = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; case GL_DST_COLOR: if (isNapalm) { dstRGB = GR_BLEND_SAME_COLOR_EXT; break; } case GL_ONE_MINUS_DST_COLOR: if (isNapalm) { dstRGB = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT; break; } default: dstRGB = GR_BLEND_ZERO; } switch ( ctx->Color.BlendDstA ) { case GL_ZERO: dstA = GR_BLEND_ZERO; break; case GL_ONE: dstA = GR_BLEND_ONE; break; case GL_SRC_COLOR: case GL_SRC_ALPHA: dstA = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; case GL_ONE_MINUS_SRC_COLOR: case GL_ONE_MINUS_SRC_ALPHA: dstA = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; case GL_DST_COLOR: case GL_DST_ALPHA: dstA = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/; break; case GL_ONE_MINUS_DST_COLOR: case GL_ONE_MINUS_DST_ALPHA: dstA = have32bpp ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; default: dstA = GR_BLEND_ZERO; } switch ( ctx->Color.BlendEquationRGB ) { case GL_FUNC_SUBTRACT: eqRGB = GR_BLEND_OP_SUB; break; case GL_FUNC_REVERSE_SUBTRACT: eqRGB = GR_BLEND_OP_REVSUB; break; case GL_FUNC_ADD: default: eqRGB = GR_BLEND_OP_ADD; break; } switch ( ctx->Color.BlendEquationA ) { case GL_FUNC_SUBTRACT: eqA = GR_BLEND_OP_SUB; break; case GL_FUNC_REVERSE_SUBTRACT: eqA = GR_BLEND_OP_REVSUB; break; case GL_FUNC_ADD: default: eqA = GR_BLEND_OP_ADD; break; } } else { /* blend disabled */ srcRGB = GR_BLEND_ONE; dstRGB = GR_BLEND_ZERO; eqRGB = GR_BLEND_OP_ADD; srcA = GR_BLEND_ONE; dstA = GR_BLEND_ZERO; eqA = GR_BLEND_OP_ADD; } if ( fxMesa->Color.AlphaFunc != func ) { fxMesa->Color.AlphaFunc = func; fxMesa->dirty |= TDFX_UPLOAD_ALPHA_TEST; } if ( fxMesa->Color.AlphaRef != ref ) { fxMesa->Color.AlphaRef = ref; fxMesa->dirty |= TDFX_UPLOAD_ALPHA_REF; } if ( fxMesa->Color.BlendSrcRGB != srcRGB || fxMesa->Color.BlendDstRGB != dstRGB || fxMesa->Color.BlendEqRGB != eqRGB || fxMesa->Color.BlendSrcA != srcA || fxMesa->Color.BlendDstA != dstA || fxMesa->Color.BlendEqA != eqA ) { fxMesa->Color.BlendSrcRGB = srcRGB; fxMesa->Color.BlendDstRGB = dstRGB; fxMesa->Color.BlendEqRGB = eqRGB; fxMesa->Color.BlendSrcA = srcA; fxMesa->Color.BlendDstA = dstA; fxMesa->Color.BlendEqA = eqA; fxMesa->dirty |= TDFX_UPLOAD_BLEND_FUNC; }}static void tdfxDDAlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref ){ tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); FLUSH_BATCH( fxMesa ); fxMesa->new_state |= TDFX_NEW_ALPHA;}static void tdfxDDBlendEquationSeparate( GLcontext *ctx, GLenum modeRGB, GLenum modeA ){ tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); assert( modeRGB == modeA ); FLUSH_BATCH( fxMesa ); fxMesa->new_state |= TDFX_NEW_ALPHA;}static void tdfxDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ){ tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); FLUSH_BATCH( fxMesa ); fxMesa->new_state |= TDFX_NEW_ALPHA; /* * XXX - Voodoo5 seems to suffer from precision problems in some * blend modes. To pass all the conformance tests we'd have to * fall back to software for many modes. Revisit someday. */}/* ============================================================= * Stipple */void tdfxUpdateStipple( GLcontext *ctx ){ tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); GrStippleMode_t mode = GR_STIPPLE_DISABLE; if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s()\n", __FUNCTION__ ); } FLUSH_BATCH( fxMesa ); if (ctx->Polygon.StippleFlag) { mode = GR_STIPPLE_PATTERN; } if ( fxMesa->Stipple.Mode != mode ) { fxMesa->Stipple.Mode = mode; fxMesa->dirty |= TDFX_UPLOAD_STIPPLE; }}/* ============================================================= * Depth testing */static void tdfxUpdateZMode( GLcontext *ctx ){ tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); GrCmpFnc_t func; FxI32 bias; FxBool mask; if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) fprintf( stderr, "%s()\n", __FUNCTION__ ); bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE); if ( ctx->Depth.Test ) { func = ctx->Depth.Func - GL_NEVER + GR_CMP_NEVER; mask = ctx->Depth.Mask; } else { /* depth testing disabled */ func = GR_CMP_ALWAYS; /* fragments always pass */ mask = FXFALSE; /* zbuffer is not touched */ } fxMesa->Depth.Clear = (FxU32) (ctx->DrawBuffer->_DepthMaxF * ctx->Depth.Clear); if ( fxMesa->Depth.Bias != bias ) { fxMesa->Depth.Bias = bias; fxMesa->dirty |= TDFX_UPLOAD_DEPTH_BIAS; } if ( fxMesa->Depth.Func != func ) { fxMesa->Depth.Func = func; fxMesa->dirty |= TDFX_UPLOAD_DEPTH_FUNC | TDFX_UPLOAD_DEPTH_MASK; } if ( fxMesa->Depth.Mask != mask ) { fxMesa->Depth.Mask = mask; fxMesa->dirty |= TDFX_UPLOAD_DEPTH_MASK; }}static void tdfxDDDepthFunc( GLcontext *ctx, GLenum func ){ tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); FLUSH_BATCH( fxMesa ); fxMesa->new_state |= TDFX_NEW_DEPTH;}static void tdfxDDDepthMask( GLcontext *ctx, GLboolean flag ){ tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); FLUSH_BATCH( fxMesa ); fxMesa->new_state |= TDFX_NEW_DEPTH;}static void tdfxDDClearDepth( GLcontext *ctx, GLclampd d ){ tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); FLUSH_BATCH( fxMesa ); fxMesa->new_state |= TDFX_NEW_DEPTH;}/* ============================================================= * Stencil *//* Evaluate all stencil state and make the Glide calls. */static GrStencil_t convertGLStencilOp( GLenum op ){ switch ( op ) { case GL_KEEP: return GR_STENCILOP_KEEP; case GL_ZERO: return GR_STENCILOP_ZERO; case GL_REPLACE: return GR_STENCILOP_REPLACE; case GL_INCR: return GR_STENCILOP_INCR_CLAMP; case GL_DECR: return GR_STENCILOP_DECR_CLAMP; case GL_INVERT: return GR_STENCILOP_INVERT; case GL_INCR_WRAP_EXT: return GR_STENCILOP_INCR_WRAP; case GL_DECR_WRAP_EXT: return GR_STENCILOP_DECR_WRAP; default: _mesa_problem( NULL, "bad stencil op in convertGLStencilOp" ); } return GR_STENCILOP_KEEP; /* never get, silence compiler warning */}static void tdfxUpdateStencil( GLcontext *ctx ){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s()\n", __FUNCTION__ ); } if (fxMesa->haveHwStencil) { if (ctx->Stencil.Enabled) { fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER + GR_CMP_NEVER; fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0] & 0xff; fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0] & 0xff; fxMesa->Stencil.WriteMask = ctx->Stencil.WriteMask[0] & 0xff; fxMesa->Stencil.FailFunc = convertGLStencilOp(ctx->Stencil.FailFunc[0]); fxMesa->Stencil.ZFailFunc = convertGLStencilOp(ctx->Stencil.ZFailFunc[0]); fxMesa->Stencil.ZPassFunc = convertGLStencilOp(ctx->Stencil.ZPassFunc[0]); fxMesa->Stencil.Clear = ctx->Stencil.Clear & 0xff; } fxMesa->dirty |= TDFX_UPLOAD_STENCIL; }}static voidtdfxDDStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -