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); }
/* None of this state is actually used for anything yet. */ static void * i915_create_blend_state(struct pipe_context *pipe, const struct pipe_blend_state *blend) { struct i915_blend_state *cso_data = CALLOC_STRUCT( i915_blend_state ); { unsigned eqRGB = blend->rt[0].rgb_func; unsigned srcRGB = blend->rt[0].rgb_src_factor; unsigned dstRGB = blend->rt[0].rgb_dst_factor; unsigned eqA = blend->rt[0].alpha_func; unsigned srcA = blend->rt[0].alpha_src_factor; unsigned dstA = blend->rt[0].alpha_dst_factor; /* Special handling for MIN/MAX filter modes handled at * state_tracker level. */ if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | IAB_ENABLE | IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR | SRC_ABLND_FACT(i915_translate_blend_factor(srcA)) | DST_ABLND_FACT(i915_translate_blend_factor(dstA)) | (i915_translate_blend_func(eqA) << IAB_FUNC_SHIFT)); } else { cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | 0); } } cso_data->modes4 |= (_3DSTATE_MODES_4_CMD | ENABLE_LOGIC_OP_FUNC | LOGIC_OP_FUNC(i915_translate_logic_op(blend->logicop_func))); if (blend->logicop_enable) cso_data->LIS5 |= S5_LOGICOP_ENABLE; if (blend->dither) cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE; /* XXX here take the target fixup into account */ if ((blend->rt[0].colormask & PIPE_MASK_R) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_RED; if ((blend->rt[0].colormask & PIPE_MASK_G) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_GREEN; if ((blend->rt[0].colormask & PIPE_MASK_B) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_BLUE; if ((blend->rt[0].colormask & PIPE_MASK_A) == 0) cso_data->LIS5 |= S5_WRITEDISABLE_ALPHA; if (blend->rt[0].blend_enable) { unsigned funcRGB = blend->rt[0].rgb_func; unsigned srcRGB = blend->rt[0].rgb_src_factor; unsigned dstRGB = blend->rt[0].rgb_dst_factor; cso_data->LIS6 |= (S6_CBUF_BLEND_ENABLE | SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) | DST_BLND_FACT(i915_translate_blend_factor(dstRGB)) | (i915_translate_blend_func(funcRGB) << S6_CBUF_BLEND_FUNC_SHIFT)); } return cso_data; }