static void i915UpdateBlendState(struct gl_context * ctx) { struct i915_context *i915 = I915_CONTEXT(ctx); GLuint iab = (i915->state.Blend[I915_BLENDREG_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.Blend[0].EquationRGB; GLuint eqA = ctx->Color.Blend[0].EquationA; GLuint srcRGB = ctx->Color.Blend[0].SrcRGB; GLuint dstRGB = ctx->Color.Blend[0].DstRGB; GLuint srcA = ctx->Color.Blend[0].SrcA; GLuint dstA = ctx->Color.Blend[0].DstA; 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.Blend[I915_BLENDREG_IAB]) { i915->state.Blend[I915_BLENDREG_IAB] = iab; I915_STATECHANGE(i915, I915_UPLOAD_BLEND); } if (lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { i915->state.Ctx[I915_CTXREG_LIS6] = lis6; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } /* This will catch a logicop blend equation */ i915EvalLogicOpBlendState(ctx); }
/** * 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 void i830_set_blend_state(struct gl_context * 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.Blend[0].SrcRGB)) | DST_BLND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].DstRGB)); switch (ctx->Color.Blend[0].EquationRGB) { 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.Blend[0].EquationRGB); return; } funcA = SRC_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].SrcA)) | DST_ABLEND_FACT(intel_translate_blend_factor(ctx->Color.Blend[0].DstA)); switch (ctx->Color.Blend[0].EquationA) { 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.Blend[0].EquationA); 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]) { I830_STATECHANGE(i830, I830_UPLOAD_CTX); i830->state.Ctx[I830_CTXREG_IALPHAB] = iab; i830->state.Ctx[I830_CTXREG_STATE1] = s1; } /* This will catch a logicop blend equation. It will also ensure * independant alpha blend is really in the correct state (either enabled * or disabled) if blending is already enabled. */ i830EvalLogicOpBlendState(ctx); if (0) { fprintf(stderr, "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n", __FUNCTION__, __LINE__, i830->state.Ctx[I830_CTXREG_STATE1], i830->state.Ctx[I830_CTXREG_IALPHAB], (ctx->Color.BlendEnabled) ? "en" : "dis"); } }