Beispiel #1
0
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);
}
Beispiel #2
0
/**
 * 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");
   }
}