📄 i915_state.c
字号:
/************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * 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, 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 TUNGSTEN GRAPHICS 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. * **************************************************************************/#include "glheader.h"#include "context.h"#include "macros.h"#include "enums.h"#include "dd.h"#include "tnl/tnl.h"#include "tnl/t_context.h"#include "texmem.h"#include "intel_fbo.h"#include "intel_screen.h"#include "intel_batchbuffer.h"#include "i915_context.h"#include "i915_reg.h"static voidi915StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref, GLuint mask){ struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func( func ); mask = mask & 0xff; if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, _mesa_lookup_enum_by_nr(func), ref, mask); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(mask)); i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | S5_STENCIL_TEST_FUNC_MASK); i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) | (test << S5_STENCIL_TEST_FUNC_SHIFT)); }static voidi915StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask){ struct i915_context *i915 = I915_CONTEXT(ctx); if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask); mask = mask & 0xff; I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(mask));}static voidi915StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail, GLenum zpass){ struct i915_context *i915 = I915_CONTEXT(ctx); int fop = intel_translate_stencil_op(fail); int dfop = intel_translate_stencil_op(zfail); int dpop = intel_translate_stencil_op(zpass); if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(fail), _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass)); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | S5_STENCIL_PASS_Z_FAIL_MASK | S5_STENCIL_PASS_Z_PASS_MASK); i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) | (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) | (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT));}static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref){ struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func( func ); GLubyte refByte; UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | S6_ALPHA_REF_MASK); i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | (((GLuint)refByte) << S6_ALPHA_REF_SHIFT));}/* This function makes sure that the proper enables are * set for LogicOp, Independant Alpha Blend, and Blending. * It needs to be called from numerous places where we * could change the LogicOp or Independant Alpha Blend without subsequent * calls to glEnable. */static void i915EvalLogicOpBlendState(GLcontext *ctx){ struct i915_context *i915 = I915_CONTEXT(ctx); I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (ctx->Color._LogicOpEnabled) { i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; } else { i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; if (ctx->Color.BlendEnabled) { i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; } else { i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; } }}static void i915BlendColor(GLcontext *ctx, const GLfloat color[4]){ struct i915_context *i915 = I915_CONTEXT(ctx); GLubyte r, g, b, a; if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = (a<<24) | (r<<16) | (g<<8) | b;}#define DST_BLND_FACT(f) ((f)<<S6_CBUF_DST_BLEND_FACT_SHIFT)#define SRC_BLND_FACT(f) ((f)<<S6_CBUF_SRC_BLEND_FACT_SHIFT)#define DST_ABLND_FACT(f) ((f)<<IAB_DST_FACTOR_SHIFT)#define SRC_ABLND_FACT(f) ((f)<<IAB_SRC_FACTOR_SHIFT)static GLuint translate_blend_equation( GLenum mode ){ switch (mode) { case GL_FUNC_ADD: return BLENDFUNC_ADD; case GL_MIN: return BLENDFUNC_MIN; case GL_MAX: return BLENDFUNC_MAX; case GL_FUNC_SUBTRACT: return BLENDFUNC_SUBTRACT; case GL_FUNC_REVERSE_SUBTRACT: return BLENDFUNC_REVERSE_SUBTRACT; default: return 0; }}static void i915UpdateBlendState( GLcontext *ctx ){ struct i915_context *i915 = I915_CONTEXT(ctx); GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] & ~(IAB_SRC_FACTOR_MASK | IAB_DST_FACTOR_MASK | (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & ~(S6_CBUF_SRC_BLEND_FACT_MASK | S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); GLuint eqRGB = ctx->Color.BlendEquationRGB; GLuint eqA = ctx->Color.BlendEquationA; GLuint srcRGB = ctx->Color.BlendSrcRGB; GLuint dstRGB = ctx->Color.BlendDstRGB; GLuint srcA = ctx->Color.BlendSrcA; GLuint dstA = ctx->Color.BlendDstA; if (eqRGB == GL_MIN || eqRGB == GL_MAX) { srcRGB = dstRGB = GL_ONE; } if (eqA == GL_MIN || eqA == GL_MAX) { srcA = dstA = GL_ONE; } lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); lis6 |= translate_blend_equation( eqRGB ) << S6_CBUF_BLEND_FUNC_SHIFT; iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); iab |= translate_blend_equation( eqA ) << IAB_FUNC_SHIFT; if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) iab |= IAB_ENABLE; if (iab != i915->state.Ctx[I915_CTXREG_IAB] || lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_IAB] = iab; i915->state.Ctx[I915_CTXREG_LIS6] = lis6; } /* This will catch a logicop blend equation */ i915EvalLogicOpBlendState(ctx);}static void i915BlendFuncSeparate(GLcontext *ctx, GLenum srcRGB, GLenum dstRGB, GLenum srcA, GLenum dstA ){ i915UpdateBlendState( ctx );}static void i915BlendEquationSeparate(GLcontext *ctx, GLenum eqRGB, GLenum eqA) { i915UpdateBlendState( ctx );}static void i915DepthFunc(GLcontext *ctx, GLenum func){ struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func( func ); if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT;}static void i915DepthMask(GLcontext *ctx, GLboolean flag){ struct i915_context *i915 = I915_CONTEXT(ctx); if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag); I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (flag && ctx->Depth.Test) i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE; else i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE;}/* ============================================================= * Polygon stipple * * The i915 supports a 4x4 stipple natively, GL wants 32x32. * Fortunately stipple is usually a repeating pattern. */static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask ){ struct i915_context *i915 = I915_CONTEXT(ctx); const GLubyte *m = mask; GLubyte p[4]; int i,j,k; int active = (ctx->Polygon.StippleFlag && i915->intel.reduced_primitive == GL_TRIANGLES); GLuint newMask; if (active) { I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); i915->state.Stipple[I915_STPREG_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 = 3 ; j >= 0; j--) for (i = 0 ; i < 4 ; i++, m++) if (*m != p[j]) { i915->intel.hw_stipple = 0; return; } newMask = (((p[0] & 0xf) << 0) | ((p[1] & 0xf) << 4) | ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); if (newMask == 0xffff || newMask == 0x0) { /* this is needed to make conform pass */ i915->intel.hw_stipple = 0; return; } i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff; i915->state.Stipple[I915_STPREG_ST1] |= newMask; i915->intel.hw_stipple = 1; if (active) i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE;}/* ============================================================= * Hardware clipping */static void i915Scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h){ struct i915_context *i915 = I915_CONTEXT(ctx); int x1, y1, x2, y2; if (!ctx->DrawBuffer) return; x1 = x; y1 = ctx->DrawBuffer->Height - (y + h); x2 = x + w - 1; y2 = y1 + h - 1; if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__, x, y, w, h); x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);}static void i915LogicOp(GLcontext *ctx, GLenum opcode){ struct i915_context *i915 = I915_CONTEXT(ctx); int tmp = intel_translate_logic_op(opcode); if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp);}static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused){ struct i915_context *i915 = I915_CONTEXT(ctx); GLuint mode; if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); if (!ctx->Polygon.CullFlag) { mode = S4_CULLMODE_NONE; } else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { mode = S4_CULLMODE_CW; if (ctx->Polygon.CullFaceMode == GL_FRONT) mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); if (ctx->Polygon.FrontFace != GL_CCW) mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); } else { mode = S4_CULLMODE_BOTH; } I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK; i915->state.Ctx[I915_CTXREG_LIS4] |= mode;}static void i915LineWidth( GLcontext *ctx, GLfloat widthf ){ struct i915_context *i915 = I915_CONTEXT( ctx ); int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; int width; if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); width = (int)(widthf * 2); CLAMP_SELF(width, 1, 0xf); lis4 |= width << S4_LINE_WIDTH_SHIFT; if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS4] = lis4; }}static void i915PointSize(GLcontext *ctx, GLfloat size){ struct i915_context *i915 = I915_CONTEXT(ctx); int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; GLint point_size = (int)size; if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); CLAMP_SELF(point_size, 1, 255); lis4 |= point_size << S4_POINT_WIDTH_SHIFT; if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS4] = lis4; }}/* ============================================================= * Color masks */static void i915ColorMask(GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a){ struct i915_context *i915 = I915_CONTEXT( ctx ); GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a); if (!r) tmp |= S5_WRITEDISABLE_RED; if (!g) tmp |= S5_WRITEDISABLE_GREEN; if (!b) tmp |= S5_WRITEDISABLE_BLUE; if (!a) tmp |= S5_WRITEDISABLE_ALPHA; if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS5] = tmp; }}static void update_specular( GLcontext *ctx ){ /* A hack to trigger the rebuild of the fragment program. */ intel_context(ctx)->NewGLState |= _NEW_TEXTURE; I915_CONTEXT(ctx)->tex_program.translated = 0; }static void i915LightModelfv(GLcontext *ctx, GLenum pname, const GLfloat *param){ if (INTEL_DEBUG&DEBUG_DRI) fprintf(stderr, "%s\n", __FUNCTION__); if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { update_specular( ctx ); }}static void i915ShadeModel(GLcontext *ctx, GLenum mode){ struct i915_context *i915 = I915_CONTEXT(ctx);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -