📄 i810state.c
字号:
/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810state.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */#include <stdio.h>#include "glheader.h"#include "context.h"#include "macros.h"#include "dd.h"#include "colormac.h"#include "texmem.h"#include "i810screen.h"#include "i810_dri.h"#include "i810context.h"#include "i810state.h"#include "i810tex.h"#include "i810vb.h"#include "i810tris.h"#include "i810ioctl.h"#include "swrast/swrast.h"#include "tnl/tnl.h"#include "vbo/vbo.h"#include "swrast_setup/swrast_setup.h"#include "tnl/t_pipeline.h"static INLINE GLuint i810PackColor(GLuint format, GLubyte r, GLubyte g, GLubyte b, GLubyte a){ if (I810_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); switch (format) { case DV_PF_555: return PACK_COLOR_1555( a, r, g, b ); case DV_PF_565: return PACK_COLOR_565( r, g, b ); default: fprintf(stderr, "unknown format %d\n", (int)format); return 0; }}static void i810AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref){ i810ContextPtr imesa = I810_CONTEXT(ctx); GLuint a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF); GLubyte refByte; CLAMPED_FLOAT_TO_UBYTE(refByte, ref); switch (ctx->Color.AlphaFunc) { case GL_NEVER: a |= ZA_ALPHA_NEVER; break; case GL_LESS: a |= ZA_ALPHA_LESS; break; case GL_GEQUAL: a |= ZA_ALPHA_GEQUAL; break; case GL_LEQUAL: a |= ZA_ALPHA_LEQUAL; break; case GL_GREATER: a |= ZA_ALPHA_GREATER; break; case GL_NOTEQUAL: a |= ZA_ALPHA_NOTEQUAL; break; case GL_EQUAL: a |= ZA_ALPHA_EQUAL; break; case GL_ALWAYS: a |= ZA_ALPHA_ALWAYS; break; default: return; } a |= ((refByte & 0xfc) << ZA_ALPHAREF_SHIFT); I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_ZA] &= ~(ZA_ALPHA_MASK|ZA_ALPHAREF_MASK); imesa->Setup[I810_CTXREG_ZA] |= a;}static void i810BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB, GLenum modeA){ assert( modeRGB == modeA ); /* Can only do GL_ADD equation in hardware */ FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_BLEND_EQ, modeRGB != GL_FUNC_ADD); /* BlendEquation sets ColorLogicOpEnabled in an unexpected * manner. */ FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_LOGICOP, (ctx->Color.ColorLogicOpEnabled && ctx->Color.LogicOp != GL_COPY));}static void i810BlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ){ i810ContextPtr imesa = I810_CONTEXT(ctx); GLuint a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND; GLboolean fallback = GL_FALSE; switch (ctx->Color.BlendSrcRGB) { case GL_ZERO: a |= SDM_SRC_ZERO; break; case GL_ONE: a |= SDM_SRC_ONE; break; case GL_SRC_COLOR: a |= SDM_SRC_SRC_COLOR; break; case GL_ONE_MINUS_SRC_COLOR: a |= SDM_SRC_INV_SRC_COLOR; break; case GL_SRC_ALPHA: a |= SDM_SRC_SRC_ALPHA; break; case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_SRC_INV_SRC_ALPHA; break; case GL_DST_ALPHA: a |= SDM_SRC_ONE; break; case GL_ONE_MINUS_DST_ALPHA: a |= SDM_SRC_ZERO; break; case GL_DST_COLOR: a |= SDM_SRC_DST_COLOR; break; case GL_ONE_MINUS_DST_COLOR: a |= SDM_SRC_INV_DST_COLOR; break; /* (f, f, f, 1), f = min(As, 1 - Ad) = min(As, 1 - 1) = 0 * So (f, f, f, 1) = (0, 0, 0, 1). Since there is no destination alpha and * the only supported alpha operation is GL_FUNC_ADD, the result modulating * the source alpha with the alpha factor is largely irrelevant. */ case GL_SRC_ALPHA_SATURATE: a |= SDM_SRC_ZERO; break; case GL_CONSTANT_COLOR: case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: fallback = GL_TRUE; break; default: return; } switch (ctx->Color.BlendDstRGB) { case GL_ZERO: a |= SDM_DST_ZERO; break; case GL_ONE: a |= SDM_DST_ONE; break; case GL_SRC_COLOR: a |= SDM_DST_SRC_COLOR; break; case GL_ONE_MINUS_SRC_COLOR: a |= SDM_DST_INV_SRC_COLOR; break; case GL_SRC_ALPHA: a |= SDM_DST_SRC_ALPHA; break; case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_DST_INV_SRC_ALPHA; break; case GL_DST_ALPHA: a |= SDM_DST_ONE; break; case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break; case GL_DST_COLOR: a |= SDM_DST_DST_COLOR; break; case GL_ONE_MINUS_DST_COLOR: a |= SDM_DST_INV_DST_COLOR; break; case GL_CONSTANT_COLOR: case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: fallback = GL_TRUE; break; default: return; } FALLBACK( imesa, I810_FALLBACK_BLEND_FUNC, fallback); if (!fallback) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_SDM] &= ~(SDM_SRC_MASK|SDM_DST_MASK); imesa->Setup[I810_CTXREG_SDM] |= a; }}static void i810DepthFunc(GLcontext *ctx, GLenum func){ i810ContextPtr imesa = I810_CONTEXT(ctx); int zmode; switch(func) { case GL_NEVER: zmode = LCS_Z_NEVER; break; case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break; case GL_LESS: zmode = LCS_Z_LESS; break; case GL_LEQUAL: zmode = LCS_Z_LEQUAL; break; case GL_EQUAL: zmode = LCS_Z_EQUAL; break; case GL_GREATER: zmode = LCS_Z_GREATER; break; case GL_GEQUAL: zmode = LCS_Z_GEQUAL; break; case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break; default: return; } I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK; imesa->Setup[I810_CTXREG_LCS] |= zmode;}static void i810DepthMask(GLcontext *ctx, GLboolean flag){ i810ContextPtr imesa = I810_CONTEXT(ctx); I810_STATECHANGE(imesa, I810_UPLOAD_CTX); if (flag) imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE; else imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE;}/* ============================================================= * Polygon stipple * * The i810 supports a 4x4 stipple natively, GL wants 32x32. * Fortunately stipple is usually a repeating pattern. */static void i810PolygonStipple( GLcontext *ctx, const GLubyte *mask ){ i810ContextPtr imesa = I810_CONTEXT(ctx); const GLubyte *m = mask; GLubyte p[4]; int i,j,k; int active = (ctx->Polygon.StippleFlag && imesa->reduced_primitive == GL_TRIANGLES); GLuint newMask; if (active) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; } p[0] = mask[12] & 0xf; p[0] |= p[0] << 4; p[1] = mask[8] & 0xf; p[1] |= p[1] << 4; p[2] = mask[4] & 0xf; p[2] |= p[2] << 4; p[3] = mask[0] & 0xf; p[3] |= p[3] << 4; for (k = 0 ; k < 8 ; k++) for (j = 0 ; j < 4; j++) for (i = 0 ; i < 4 ; i++) if (*m++ != p[j]) { imesa->stipple_in_hw = 0; return; } newMask = ((p[0] & 0xf) << 0) | ((p[1] & 0xf) << 4) | ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12); if (newMask == 0xffff) { /* this is needed to make conform pass */ imesa->stipple_in_hw = 0; return; } imesa->Setup[I810_CTXREG_ST1] &= ~0xffff; imesa->Setup[I810_CTXREG_ST1] |= newMask; imesa->stipple_in_hw = 1; if (active) imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;}/* ============================================================= * Hardware clipping */static void i810Scissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ){ i810ContextPtr imesa = I810_CONTEXT(ctx); if (ctx->Scissor.Enabled) { I810_FIREVERTICES(imesa); /* don't pipeline cliprect changes */ imesa->upload_cliprects = GL_TRUE; } imesa->scissor_rect.x1 = x; imesa->scissor_rect.y1 = imesa->driDrawable->h - (y + h); imesa->scissor_rect.x2 = x + w; imesa->scissor_rect.y2 = imesa->driDrawable->h - y;}static void i810LogicOp( GLcontext *ctx, GLenum opcode ){ i810ContextPtr imesa = I810_CONTEXT(ctx); FALLBACK( imesa, I810_FALLBACK_LOGICOP, (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) );}/* Fallback to swrast for select and feedback. */static void i810RenderMode( GLcontext *ctx, GLenum mode ){ i810ContextPtr imesa = I810_CONTEXT(ctx); FALLBACK( imesa, I810_FALLBACK_RENDERMODE, (mode != GL_RENDER) );}void i810DrawBuffer(GLcontext *ctx, GLenum mode ){ i810ContextPtr imesa = I810_CONTEXT(ctx); int front = 0; if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_TRUE ); return; } switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0]) { case BUFFER_FRONT_LEFT: front = 1; break; case BUFFER_BACK_LEFT: front = 0; break; default: FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_TRUE ); return; } if ( imesa->sarea->pf_current_page == 1 ) front ^= 1; FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_FALSE ); I810_FIREVERTICES(imesa); I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS); if (front) { imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset | imesa->i810Screen->backPitchBits); i810XMesaSetFrontClipRects( imesa ); } else { imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset | imesa->i810Screen->backPitchBits); i810XMesaSetBackClipRects( imesa ); }}static void i810ReadBuffer(GLcontext *ctx, GLenum mode ){ /* XXX anything? */}static void i810ClearColor(GLcontext *ctx, const GLfloat color[4] ){ i810ContextPtr imesa = I810_CONTEXT(ctx); GLubyte c[4]; CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat, c[0], c[1], c[2], c[3] );}/* ============================================================= * Culling - the i810 isn't quite as clean here as the rest of * its interfaces, but it's not bad. */static void i810CullFaceFrontFace(GLcontext *ctx, GLenum unused){ i810ContextPtr imesa = I810_CONTEXT(ctx); GLuint mode = LCS_CULL_BOTH; if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { mode = LCS_CULL_CW; if (ctx->Polygon.CullFaceMode == GL_FRONT) mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW); if (ctx->Polygon.FrontFace != GL_CCW) mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW); } imesa->LcsCullMode = mode; if (ctx->Polygon.CullFlag) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK; imesa->Setup[I810_CTXREG_LCS] |= mode; }}static void i810LineWidth( GLcontext *ctx, GLfloat widthf ){ i810ContextPtr imesa = I810_CONTEXT( ctx ); /* AA, non-AA limits are same */ const int width = (int) CLAMP(ctx->Line.Width, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth); imesa->LcsLineWidth = 0; if (width & 1) imesa->LcsLineWidth |= LCS_LINEWIDTH_1_0; if (width & 2) imesa->LcsLineWidth |= LCS_LINEWIDTH_2_0; if (imesa->reduced_primitive == GL_LINES) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0; imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsLineWidth; }}static void i810PointSize( GLcontext *ctx, GLfloat sz ){ i810ContextPtr imesa = I810_CONTEXT( ctx ); /* AA, non-AA limits are same */ const int size = (int) CLAMP(ctx->Point.Size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize); imesa->LcsPointSize = 0; if (size & 1) imesa->LcsPointSize |= LCS_LINEWIDTH_1_0; if (size & 2) imesa->LcsPointSize |= LCS_LINEWIDTH_2_0; if (imesa->reduced_primitive == GL_POINTS) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0; imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsPointSize; }}/* ============================================================= * Color masks */static void i810ColorMask(GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a ){ i810ContextPtr imesa = I810_CONTEXT( ctx ); GLuint tmp = 0; if (r && g && b) { tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE; FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE ); } else if (!r && !g && !b) { tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE; FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE ); } else { FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_TRUE ); return; } if (tmp != imesa->Setup[I810_CTXREG_B2]) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_B2] = tmp; imesa->dirty |= I810_UPLOAD_CTX; }}/* Seperate specular not fully implemented on the i810. */static void i810LightModelfv(GLcontext *ctx, GLenum pname, const GLfloat *param){ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { i810ContextPtr imesa = I810_CONTEXT( ctx ); FALLBACK( imesa, I810_FALLBACK_SPECULAR, (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)); }}/* But the 815 has it... */static void i810LightModelfv_i815(GLcontext *ctx, GLenum pname, const GLfloat *param){ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { i810ContextPtr imesa = I810_CONTEXT( ctx ); I810_STATECHANGE(imesa, I810_UPLOAD_CTX); if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) imesa->Setup[I810_CTXREG_B1] |= B1_SPEC_ENABLE; else imesa->Setup[I810_CTXREG_B1] &= ~B1_SPEC_ENABLE; }}/* In Mesa 3.5 we can reliably do native flatshading. */static void i810ShadeModel(GLcontext *ctx, GLenum mode){ i810ContextPtr imesa = I810_CONTEXT(ctx); I810_STATECHANGE(imesa, I810_UPLOAD_CTX); if (mode == GL_FLAT) imesa->Setup[I810_CTXREG_LCS] |= LCS_INTERP_FLAT; else imesa->Setup[I810_CTXREG_LCS] &= ~LCS_INTERP_FLAT;}/* ============================================================= * Fog */static void i810Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param){ i810ContextPtr imesa = I810_CONTEXT(ctx); if (pname == GL_FOG_COLOR) { GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) | ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) | ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -