static void vrend_hw_emit_blend(struct vrend_sub_context *sub_ctx, struct pipe_blend_state *state)
{
   if (state->logicop_enable != sub_ctx->hw_blend_state.logicop_enable) {
      sub_ctx->hw_blend_state.logicop_enable = state->logicop_enable;
      if (vrend_state.use_gles) {
         if (can_emulate_logicop(state->logicop_func))
            sub_ctx->shader_dirty = true;
         else
            report_gles_warn(sub_ctx->parent, GLES_WARN_LOGIC_OP);
      } else if (state->logicop_enable) {
         glEnable(GL_COLOR_LOGIC_OP);
         glLogicOp(translate_logicop(state->logicop_func));
      } else {
         glDisable(GL_COLOR_LOGIC_OP);
      }
   }

   if (state->independent_blend_enable &&
       has_feature(feat_indep_blend) &&
       has_feature(feat_indep_blend_func)) {
      /* ARB_draw_buffers_blend is required for this */
      int i;

      for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {

         if (state->rt[i].blend_enable) {
            bool dual_src = util_blend_state_is_dual(&sub_ctx->blend_state, i);
            if (dual_src && !has_feature(feat_dual_src_blend)) {
               vrend_printf( "dual src blend requested but not supported for rt %d\n", i);
               continue;
            }

            glBlendFuncSeparateiARB(i, translate_blend_factor(state->rt[i].rgb_src_factor),
                                    translate_blend_factor(state->rt[i].rgb_dst_factor),
                                    translate_blend_factor(state->rt[i].alpha_src_factor),
                                    translate_blend_factor(state->rt[i].alpha_dst_factor));
            glBlendEquationSeparateiARB(i, translate_blend_func(state->rt[i].rgb_func),
                                        translate_blend_func(state->rt[i].alpha_func));
            glEnableIndexedEXT(GL_BLEND, i);
         } else
            glDisableIndexedEXT(GL_BLEND, i);

         if (state->rt[i].colormask != sub_ctx->hw_blend_state.rt[i].colormask) {
            sub_ctx->hw_blend_state.rt[i].colormask = state->rt[i].colormask;
            glColorMaskIndexedEXT(i, state->rt[i].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE,
                                  state->rt[i].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE,
                                  state->rt[i].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE,
                                  state->rt[i].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE);
         }
      }
   } else {
      if (state->rt[0].blend_enable) {
         bool dual_src = util_blend_state_is_dual(&sub_ctx->blend_state, 0);
         if (dual_src && !has_feature(feat_dual_src_blend)) {
            vrend_printf( "dual src blend requested but not supported for rt 0\n");
         }
         glBlendFuncSeparate(translate_blend_factor(state->rt[0].rgb_src_factor),
                             translate_blend_factor(state->rt[0].rgb_dst_factor),
                             translate_blend_factor(state->rt[0].alpha_src_factor),
                             translate_blend_factor(state->rt[0].alpha_dst_factor));
         glBlendEquationSeparate(translate_blend_func(state->rt[0].rgb_func),
                                 translate_blend_func(state->rt[0].alpha_func));
         glEnable(GL_BLEND);
      }
      else
         glDisable(GL_BLEND);

      if (state->rt[0].colormask != sub_ctx->hw_blend_state.rt[0].colormask ||
          (sub_ctx->hw_blend_state.independent_blend_enable &&
           !state->independent_blend_enable)) {
         int i;
         for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
            sub_ctx->hw_blend_state.rt[i].colormask = state->rt[i].colormask;
         glColorMask(state->rt[0].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE,
                     state->rt[0].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE,
                     state->rt[0].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE,
                     state->rt[0].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE);
      }
   }
   sub_ctx->hw_blend_state.independent_blend_enable = state->independent_blend_enable;

   if (has_feature(feat_multisample)) {
      if (state->alpha_to_coverage)
         glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
      else
         glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);

      if (!vrend_state.use_gles) {
         if (state->alpha_to_one)
            glEnable(GL_SAMPLE_ALPHA_TO_ONE);
         else
            glDisable(GL_SAMPLE_ALPHA_TO_ONE);
      }
   }

   if (state->dither)
      glEnable(GL_DITHER);
   else
      glDisable(GL_DITHER);
}
static void vrend_hw_emit_blend(struct vrend_sub_context *sub_ctx, struct pipe_blend_state *state)
{
   if (state->logicop_enable != sub_ctx->hw_blend_state.logicop_enable) {
      sub_ctx->hw_blend_state.logicop_enable = state->logicop_enable;
      if (vrend_state.use_gles) {
         if (can_emulate_logicop(state->logicop_func))
            sub_ctx->shader_dirty = true;
         else
            report_gles_warn(sub_ctx->parent, GLES_WARN_LOGIC_OP);
      } else if (state->logicop_enable) {
         glEnable(GL_COLOR_LOGIC_OP);
         glLogicOp(translate_logicop(state->logicop_func));
      } else {
         glDisable(GL_COLOR_LOGIC_OP);
      }
   }

   if (state->independent_blend_enable &&
       has_feature(feat_indep_blend) &&
       has_feature(feat_indep_blend_func)) {
       
      int i;

      for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {

         if (state->rt[i].blend_enable) {
            bool dual_src = util_blend_state_is_dual(&sub_ctx->blend_state, i);
            if (dual_src && !has_feature(feat_dual_src_blend)) {
               vrend_printf( "dual src blend requested but not supported for rt %d\n", i);
               continue;
            }

            glBlendFuncSeparateiARB(i, translate_blend_factor(state->rt[i].rgb_src_factor),
                                    translate_blend_factor(state->rt[i].rgb_dst_factor),
                                    translate_blend_factor(state->rt[i].alpha_src_factor),
                                    translate_blend_factor(state->rt[i].alpha_dst_factor));
            glBlendEquationSeparateiARB(i, translate_blend_func(state->rt[i].rgb_func),
                                        translate_blend_func(state->rt[i].alpha_func));
            glEnableIndexedEXT(GL_BLEND, i);
         } else
            glDisableIndexedEXT(GL_BLEND, i);

         if (state->rt[i].colormask != sub_ctx->hw_blend_state.rt[i].colormask) {
            sub_ctx->hw_blend_state.rt[i].colormask = state->rt[i].colormask;
            glColorMaskIndexedEXT(i, state->rt[i].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE,
                                  state->rt[i].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE,
                                  state->rt[i].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE,
                                  state->rt[i].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE);
         }
      }
   } else {
      if (state->rt[0].blend_enable) {
         bool dual_src = util_blend_state_is_dual(&sub_ctx->blend_state, 0);
         if (dual_src && !has_feature(feat_dual_src_blend)) {
            vrend_printf( "dual src blend requested but not supported for rt 0\n");
         }
         glBlendFuncSeparate(translate_blend_factor(state->rt[0].rgb_src_factor),
                             translate_blend_factor(state->rt[0].rgb_dst_factor),
                             translate_blend_factor(state->rt[0].alpha_src_factor),
                             translate_blend_factor(state->rt[0].alpha_dst_factor));
         glBlendEquationSeparate(translate_blend_func(state->rt[0].rgb_func),
                                 translate_blend_func(state->rt[0].alpha_func));
         glEnable(GL_BLEND);
      }
      else
         glDisable(GL_BLEND);

      if (state->rt[0].colormask != sub_ctx->hw_blend_state.rt[0].colormask ||
          (sub_ctx->hw_blend_state.independent_blend_enable &&
           !state->independent_blend_enable)) {
         int i;
         for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
            sub_ctx->hw_blend_state.rt[i].colormask = state->rt[i].colormask;
         glColorMask(state->rt[0].colormask & PIPE_MASK_R ? GL_TRUE : GL_FALSE,
                     state->rt[0].colormask & PIPE_MASK_G ? GL_TRUE : GL_FALSE,
                     state->rt[0].colormask & PIPE_MASK_B ? GL_TRUE : GL_FALSE,
                     state->rt[0].colormask & PIPE_MASK_A ? GL_TRUE : GL_FALSE);
      }
   }
   sub_ctx->hw_blend_state.independent_blend_enable = state->independent_blend_enable;

   if (has_feature(feat_multisample)) {
      if (state->alpha_to_coverage)
         glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
      else
         glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);

      if (!vrend_state.use_gles) {
         if (state->alpha_to_one)
            glEnable(GL_SAMPLE_ALPHA_TO_ONE);
         else
            glDisable(GL_SAMPLE_ALPHA_TO_ONE);
      }
   }

   if (state->dither)
      glEnable(GL_DITHER);
   else
      glDisable(GL_DITHER);
}