📄 mgastate.c
字号:
/* * Copyright 2000-2001 VA Linux Systems, Inc. * 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 * on the rights to use, copy, modify, merge, publish, distribute, sub * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. * * Authors: * Keith Whitwell <keith@tungstengraphics.com> */#include "mtypes.h"#include "colormac.h"#include "dd.h"#include "mm.h"#include "mgacontext.h"#include "mgadd.h"#include "mgastate.h"#include "mgatex.h"#include "mgavb.h"#include "mgatris.h"#include "mgaioctl.h"#include "mgaregs.h"#include "swrast/swrast.h"#include "vbo/vbo.h"#include "tnl/tnl.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"#include "swrast_setup/swrast_setup.h"#include "xmlpool.h"#include "drirenderbuffer.h"static void updateSpecularLighting( GLcontext *ctx );static const GLuint mgarop_NoBLK[16] = { DC_atype_rpl | 0x00000000, DC_atype_rstr | 0x00080000, DC_atype_rstr | 0x00040000, DC_atype_rpl | 0x000c0000, DC_atype_rstr | 0x00020000, DC_atype_rstr | 0x000a0000, DC_atype_rstr | 0x00060000, DC_atype_rstr | 0x000e0000, DC_atype_rstr | 0x00010000, DC_atype_rstr | 0x00090000, DC_atype_rstr | 0x00050000, DC_atype_rstr | 0x000d0000, DC_atype_rpl | 0x00030000, DC_atype_rstr | 0x000b0000, DC_atype_rstr | 0x00070000, DC_atype_rpl | 0x000f0000};/* ============================================================= * Alpha blending */static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLubyte refByte; GLuint a; CLAMPED_FLOAT_TO_UBYTE(refByte, ref); switch ( func ) { case GL_NEVER: a = AC_atmode_alt; refByte = 0; break; case GL_LESS: a = AC_atmode_alt; break; case GL_GEQUAL: a = AC_atmode_agte; break; case GL_LEQUAL: a = AC_atmode_alte; break; case GL_GREATER: a = AC_atmode_agt; break; case GL_NOTEQUAL: a = AC_atmode_ane; break; case GL_EQUAL: a = AC_atmode_ae; break; case GL_ALWAYS: a = AC_atmode_noacmp; break; default: a = 0; break; } MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->hw.alpha_func = a | MGA_FIELD( AC_atref, refByte );}static void updateBlendLogicOp(GLcontext *ctx){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLboolean logicOp = RGBA_LOGICOP_ENABLED(ctx); MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->hw.blend_func_enable = (ctx->Color.BlendEnabled && !logicOp) ? ~0 : 0; FALLBACK( ctx, MGA_FALLBACK_BLEND, ctx->Color.BlendEnabled && !logicOp && mmesa->hw.blend_func == (AC_src_src_alpha_sat | AC_dst_zero) );}static void mgaDDBlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA){ assert( modeRGB == modeA ); updateBlendLogicOp( ctx );}static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); GLuint src; GLuint dst; switch (ctx->Color.BlendSrcRGB) { case GL_ZERO: src = AC_src_zero; break; case GL_SRC_ALPHA: src = AC_src_src_alpha; break; case GL_ONE: default: /* never happens */ src = AC_src_one; break; case GL_DST_COLOR: src = AC_src_dst_color; break; case GL_ONE_MINUS_DST_COLOR: src = AC_src_om_dst_color; break; case GL_ONE_MINUS_SRC_ALPHA: src = AC_src_om_src_alpha; break; case GL_DST_ALPHA: src = (ctx->Visual.alphaBits > 0) ? AC_src_dst_alpha : AC_src_one; break; case GL_ONE_MINUS_DST_ALPHA: src = (ctx->Visual.alphaBits > 0) ? AC_src_om_dst_alpha : AC_src_zero; break; case GL_SRC_ALPHA_SATURATE: src = (ctx->Visual.alphaBits > 0) ? AC_src_src_alpha_sat : AC_src_zero; break; } switch (ctx->Color.BlendDstRGB) { case GL_SRC_ALPHA: dst = AC_dst_src_alpha; break; case GL_ONE_MINUS_SRC_ALPHA: dst = AC_dst_om_src_alpha; break; default: /* never happens */ case GL_ZERO: dst = AC_dst_zero; break; case GL_ONE: dst = AC_dst_one; break; case GL_SRC_COLOR: dst = AC_dst_src_color; break; case GL_ONE_MINUS_SRC_COLOR: dst = AC_dst_om_src_color; break; case GL_DST_ALPHA: dst = (ctx->Visual.alphaBits > 0) ? AC_dst_dst_alpha : AC_dst_one; break; case GL_ONE_MINUS_DST_ALPHA: dst = (ctx->Visual.alphaBits > 0) ? AC_dst_om_dst_alpha : AC_dst_zero; break; } MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->hw.blend_func = (src | dst); FALLBACK( ctx, MGA_FALLBACK_BLEND, ctx->Color.BlendEnabled && !RGBA_LOGICOP_ENABLED(ctx) && mmesa->hw.blend_func == (AC_src_src_alpha_sat | AC_dst_zero) );}/* ============================================================= * Depth testing */static void mgaDDDepthFunc(GLcontext *ctx, GLenum func){ mgaContextPtr mmesa = MGA_CONTEXT( ctx ); int zmode; switch (func) { case GL_NEVER: /* can't do this in h/w, we'll use a s/w fallback */ FALLBACK (ctx, MGA_FALLBACK_DEPTH, ctx->Depth.Test); /* FALLTHROUGH */ case GL_ALWAYS: zmode = DC_zmode_nozcmp; break; case GL_LESS: zmode = DC_zmode_zlt; break; case GL_LEQUAL: zmode = DC_zmode_zlte; break; case GL_EQUAL: zmode = DC_zmode_ze; break; case GL_GREATER: zmode = DC_zmode_zgt; break; case GL_GEQUAL: zmode = DC_zmode_zgte; break; case GL_NOTEQUAL: zmode = DC_zmode_zne; break; default: zmode = 0; break; } MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->hw.zmode &= DC_zmode_MASK; mmesa->hw.zmode |= zmode;}static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag){ mgaContextPtr mmesa = MGA_CONTEXT( ctx ); MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->hw.zmode &= DC_atype_MASK; mmesa->hw.zmode |= (flag) ? DC_atype_zi : DC_atype_i;}static void mgaDDClearDepth(GLcontext *ctx, GLclampd d){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); /* Select the Z depth. The ~ is used because the _MASK values in the * MGA driver are used to mask OFF the selected bits. In this case, * we want to mask off everything except the MA_zwidth bits. */ switch (mmesa->setup.maccess & ~MA_zwidth_MASK) { case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break; case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break; case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break; default: return; }}/* ============================================================= * Fog */static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); if (pname == GL_FOG_COLOR) { GLuint color = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F), (GLubyte)(ctx->Fog.Color[1]*255.0F), (GLubyte)(ctx->Fog.Color[2]*255.0F)); MGA_STATECHANGE(mmesa, MGA_UPLOAD_CONTEXT); mmesa->setup.fogcolor = color; }}/* ============================================================= * Scissoring */void mgaUpdateClipping(const GLcontext *ctx){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); if (mmesa->driDrawable) { int x1 = mmesa->driDrawable->x + ctx->Scissor.X; int y1 = mmesa->driDrawable->y + mmesa->driDrawable->h - (ctx->Scissor.Y + ctx->Scissor.Height); int x2 = x1 + ctx->Scissor.Width; int y2 = y1 + ctx->Scissor.Height; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 < 0) x2 = 0; if (y2 < 0) y2 = 0; mmesa->scissor_rect.x1 = x1; mmesa->scissor_rect.y1 = y1; mmesa->scissor_rect.x2 = x2; mmesa->scissor_rect.y2 = y2; mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; }}static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ){ if ( ctx->Scissor.Enabled ) { FLUSH_BATCH( MGA_CONTEXT(ctx) ); /* don't pipeline cliprect changes */ mgaUpdateClipping( ctx ); }}/* ============================================================= * Culling */#define _CULL_DISABLE 0#define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16))#define _CULL_POSITIVE (1<<11)static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum unused){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { mmesa->hw.cull = _CULL_NEGATIVE; if (ctx->Polygon.CullFaceMode == GL_FRONT) mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); if (ctx->Polygon.FrontFace != GL_CCW) mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); mmesa->hw.cull_dualtex = mmesa->hw.cull ^ (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* warp bug? */ } else { mmesa->hw.cull = _CULL_DISABLE; mmesa->hw.cull_dualtex = _CULL_DISABLE; }}/* ============================================================= * Masks */static void mgaDDColorMask(GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a ){ mgaContextPtr mmesa = MGA_CONTEXT( ctx ); mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; GLuint mask = mgaPackColor(mgaScreen->cpp, ctx->Color.ColorMask[RCOMP], ctx->Color.ColorMask[GCOMP], ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP]); if (mgaScreen->cpp == 2) mask = mask | (mask << 16); if (mmesa->setup.plnwt != mask) { MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT ); mmesa->setup.plnwt = mask; }}/* ============================================================= * Polygon state */static int mgaStipples[16] = { 0xffff, 0xa5a5,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -