📄 i830_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 "texmem.h"#include "drivers/common/driverfuncs.h"#include "intel_screen.h"#include "intel_batchbuffer.h"#include "intel_fbo.h"#include "i830_context.h"#include "i830_reg.h"#define FILE_DEBUG_FLAG DEBUG_STATEstatic voidi830StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, GLuint mask){ struct i830_context *i830 = i830_context(ctx); int test = intel_translate_compare_func(func); mask = mask & 0xff; DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, _mesa_lookup_enum_by_nr(func), ref, mask); I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(mask)); i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK | ENABLE_STENCIL_TEST_FUNC_MASK); i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE | ENABLE_STENCIL_TEST_FUNC | STENCIL_REF_VALUE(ref) | STENCIL_TEST_FUNC(test));}static voidi830StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask){ struct i830_context *i830 = i830_context(ctx); DBG("%s : mask 0x%x\n", __FUNCTION__, mask); mask = mask & 0xff; I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(mask));}static voidi830StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, GLenum zpass){ struct i830_context *i830 = i830_context(ctx); int fop, dfop, dpop; DBG("%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)); fop = 0; dfop = 0; dpop = 0; switch (fail) { case GL_KEEP: fop = STENCILOP_KEEP; break; case GL_ZERO: fop = STENCILOP_ZERO; break; case GL_REPLACE: fop = STENCILOP_REPLACE; break; case GL_INCR: fop = STENCILOP_INCRSAT; break; case GL_DECR: fop = STENCILOP_DECRSAT; break; case GL_INCR_WRAP: fop = STENCILOP_INCR; break; case GL_DECR_WRAP: fop = STENCILOP_DECR; break; case GL_INVERT: fop = STENCILOP_INVERT; break; default: break; } switch (zfail) { case GL_KEEP: dfop = STENCILOP_KEEP; break; case GL_ZERO: dfop = STENCILOP_ZERO; break; case GL_REPLACE: dfop = STENCILOP_REPLACE; break; case GL_INCR: dfop = STENCILOP_INCRSAT; break; case GL_DECR: dfop = STENCILOP_DECRSAT; break; case GL_INCR_WRAP: dfop = STENCILOP_INCR; break; case GL_DECR_WRAP: dfop = STENCILOP_DECR; break; case GL_INVERT: dfop = STENCILOP_INVERT; break; default: break; } switch (zpass) { case GL_KEEP: dpop = STENCILOP_KEEP; break; case GL_ZERO: dpop = STENCILOP_ZERO; break; case GL_REPLACE: dpop = STENCILOP_REPLACE; break; case GL_INCR: dpop = STENCILOP_INCRSAT; break; case GL_DECR: dpop = STENCILOP_DECRSAT; break; case GL_INCR_WRAP: dpop = STENCILOP_INCR; break; case GL_DECR_WRAP: dpop = STENCILOP_DECR; break; case GL_INVERT: dpop = STENCILOP_INVERT; break; default: break; } I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK); i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS | STENCIL_FAIL_OP(fop) | STENCIL_PASS_DEPTH_FAIL_OP (dfop) | STENCIL_PASS_DEPTH_PASS_OP (dpop));}static voidi830AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref){ struct i830_context *i830 = i830_context(ctx); int test = intel_translate_compare_func(func); GLubyte refByte; GLuint refInt; UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); refInt = (GLuint) refByte; I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK; i830->state.Ctx[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC | ENABLE_ALPHA_REF_VALUE | ALPHA_TEST_FUNC(test) | ALPHA_REF_VALUE(refInt));}/** * 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. * * \todo * This function is substantially different from the old i830-specific driver. * I'm not sure which is correct. */static voidi830EvalLogicOpBlendState(GLcontext * ctx){ struct i830_context *i830 = i830_context(ctx); I830_STATECHANGE(i830, I830_UPLOAD_CTX); if (RGBA_LOGICOP_ENABLED(ctx)) { i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | ENABLE_LOGIC_OP_MASK); i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | ENABLE_LOGIC_OP); } else if (ctx->Color.BlendEnabled) { i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | ENABLE_LOGIC_OP_MASK); i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND | DISABLE_LOGIC_OP); } else { i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND | ENABLE_LOGIC_OP_MASK); i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND | DISABLE_LOGIC_OP); }}static voidi830BlendColor(GLcontext * ctx, const GLfloat color[4]){ struct i830_context *i830 = i830_context(ctx); GLubyte r, g, b, a; DBG("%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]); I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = (a << 24) | (r << 16) | (g << 8) | b;}/** * Sets both the blend equation (called "function" in i830 docs) and the * blend function (called "factor" in i830 docs). This is done in a single * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX) * change the interpretation of the blend function. */static voidi830_set_blend_state(GLcontext * ctx){ struct i830_context *i830 = i830_context(ctx); int funcA; int funcRGB; int eqnA; int eqnRGB; int iab; int s1; funcRGB = SRC_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcRGB)) | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstRGB)); switch (ctx->Color.BlendEquationRGB) { case GL_FUNC_ADD: eqnRGB = BLENDFUNC_ADD; break; case GL_MIN: eqnRGB = BLENDFUNC_MIN; funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); break; case GL_MAX: eqnRGB = BLENDFUNC_MAX; funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); break; case GL_FUNC_SUBTRACT: eqnRGB = BLENDFUNC_SUB; break; case GL_FUNC_REVERSE_SUBTRACT: eqnRGB = BLENDFUNC_RVRSE_SUB; break; default: fprintf(stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n", __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB); return; } funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendSrcA)) | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.BlendDstA)); switch (ctx->Color.BlendEquationA) { case GL_FUNC_ADD: eqnA = BLENDFUNC_ADD; break; case GL_MIN: eqnA = BLENDFUNC_MIN; funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); break; case GL_MAX: eqnA = BLENDFUNC_MAX; funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE); break; case GL_FUNC_SUBTRACT: eqnA = BLENDFUNC_SUB; break; case GL_FUNC_REVERSE_SUBTRACT: eqnA = BLENDFUNC_RVRSE_SUB; break; default: fprintf(stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n", __FUNCTION__, __LINE__, ctx->Color.BlendEquationA); return; } iab = eqnA | funcA | _3DSTATE_INDPT_ALPHA_BLEND_CMD | ENABLE_SRC_ABLEND_FACTOR | ENABLE_DST_ABLEND_FACTOR | ENABLE_ALPHA_BLENDFUNC; s1 = eqnRGB | funcRGB | _3DSTATE_MODES_1_CMD | ENABLE_SRC_BLND_FACTOR | ENABLE_DST_BLND_FACTOR | ENABLE_COLR_BLND_FUNC; if ((eqnA | funcA) != (eqnRGB | funcRGB)) iab |= ENABLE_INDPT_ALPHA_BLEND; else iab |= DISABLE_INDPT_ALPHA_BLEND; if (iab != i830->state.Ctx[I830_CTXREG_IALPHAB] || s1 != i830->state.Ctx[I830_CTXREG_STATE1]) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -