/** * Set the separate blend source/dest factors for all draw buffers. * * \param sfactorRGB RGB source factor operator. * \param dfactorRGB RGB destination factor operator. * \param sfactorA alpha source factor operator. * \param dfactorA alpha destination factor operator. */ void GLAPIENTRY _mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n", _mesa_enum_to_string(sfactorRGB), _mesa_enum_to_string(dfactorRGB), _mesa_enum_to_string(sfactorA), _mesa_enum_to_string(dfactorA)); if (skip_blend_state_update(ctx, sfactorRGB, dfactorRGB, sfactorA, dfactorA)) return; if (!validate_blend_factors(ctx, "glBlendFuncSeparate", sfactorRGB, dfactorRGB, sfactorA, dfactorA)) { return; } blend_func_separate(ctx, sfactorRGB, dfactorRGB, sfactorA, dfactorA); }
/** * Set the separate blend source/dest factors for all draw buffers. * * \param sfactorRGB RGB source factor operator. * \param dfactorRGB RGB destination factor operator. * \param sfactorA alpha source factor operator. * \param dfactorA alpha destination factor operator. */ void GLAPIENTRY _mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { GLuint buf, numBuffers; GLboolean changed; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n", _mesa_lookup_enum_by_nr(sfactorRGB), _mesa_lookup_enum_by_nr(dfactorRGB), _mesa_lookup_enum_by_nr(sfactorA), _mesa_lookup_enum_by_nr(dfactorA)); if (!validate_blend_factors(ctx, "glBlendFuncSeparate", sfactorRGB, dfactorRGB, sfactorA, dfactorA)) { return; } numBuffers = ctx->Extensions.ARB_draw_buffers_blend ? ctx->Const.MaxDrawBuffers : 1; changed = GL_FALSE; for (buf = 0; buf < numBuffers; buf++) { if (ctx->Color.Blend[buf].SrcRGB != sfactorRGB || ctx->Color.Blend[buf].DstRGB != dfactorRGB || ctx->Color.Blend[buf].SrcA != sfactorA || ctx->Color.Blend[buf].DstA != dfactorA) { changed = GL_TRUE; break; } } if (!changed) return; FLUSH_VERTICES(ctx, _NEW_COLOR); for (buf = 0; buf < numBuffers; buf++) { ctx->Color.Blend[buf].SrcRGB = sfactorRGB; ctx->Color.Blend[buf].DstRGB = dfactorRGB; ctx->Color.Blend[buf].SrcA = sfactorA; ctx->Color.Blend[buf].DstA = dfactorA; update_uses_dual_src(ctx, buf); } ctx->Color._BlendFuncPerBuffer = GL_FALSE; if (ctx->Driver.BlendFuncSeparate) { ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB, sfactorA, dfactorA); } }
/** * Specify the blending operation. * * \param sfactor source factor operator. * \param dfactor destination factor operator. * * \sa glBlendFunc, glBlendFuncSeparateEXT */ void GLAPIENTRY _mesa_BlendFunc( GLenum sfactor, GLenum dfactor ) { GET_CURRENT_CONTEXT(ctx); if (skip_blend_state_update(ctx, sfactor, dfactor, sfactor, dfactor)) return; if (!validate_blend_factors(ctx, "glBlendFunc", sfactor, dfactor, sfactor, dfactor)) { return; } blend_func_separate(ctx, sfactor, dfactor, sfactor, dfactor); }
/** * Set separate blend source/dest factors for one color buffer/target. */ void GLAPIENTRY _mesa_BlendFuncSeparateiARB(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (!ctx->Extensions.ARB_draw_buffers_blend) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlendFunc[Separate]i()"); return; } if (buf >= ctx->Const.MaxDrawBuffers) { _mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)", buf); return; } if (!validate_blend_factors(ctx, "glBlendFuncSeparatei", sfactorRGB, dfactorRGB, sfactorA, dfactorA)) { return; } if (ctx->Color.Blend[buf].SrcRGB == sfactorRGB && ctx->Color.Blend[buf].DstRGB == dfactorRGB && ctx->Color.Blend[buf].SrcA == sfactorA && ctx->Color.Blend[buf].DstA == dfactorA) return; /* no change */ FLUSH_VERTICES(ctx, _NEW_COLOR); ctx->Color.Blend[buf].SrcRGB = sfactorRGB; ctx->Color.Blend[buf].DstRGB = dfactorRGB; ctx->Color.Blend[buf].SrcA = sfactorA; ctx->Color.Blend[buf].DstA = dfactorA; update_uses_dual_src(ctx, buf); ctx->Color._BlendFuncPerBuffer = GL_TRUE; if (ctx->Driver.BlendFuncSeparatei) { ctx->Driver.BlendFuncSeparatei(ctx, buf, sfactorRGB, dfactorRGB, sfactorA, dfactorA); } }
static ALWAYS_INLINE void blend_func_separatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA, bool no_error) { GET_CURRENT_CONTEXT(ctx); if (!no_error) { if (!ctx->Extensions.ARB_draw_buffers_blend) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlendFunc[Separate]i()"); return; } if (buf >= ctx->Const.MaxDrawBuffers) { _mesa_error(ctx, GL_INVALID_VALUE, "glBlendFuncSeparatei(buffer=%u)", buf); return; } } if (ctx->Color.Blend[buf].SrcRGB == sfactorRGB && ctx->Color.Blend[buf].DstRGB == dfactorRGB && ctx->Color.Blend[buf].SrcA == sfactorA && ctx->Color.Blend[buf].DstA == dfactorA) return; /* no change */ if (!no_error && !validate_blend_factors(ctx, "glBlendFuncSeparatei", sfactorRGB, dfactorRGB, sfactorA, dfactorA)) { return; } FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlend ? 0 : _NEW_COLOR); ctx->NewDriverState |= ctx->DriverFlags.NewBlend; ctx->Color.Blend[buf].SrcRGB = sfactorRGB; ctx->Color.Blend[buf].DstRGB = dfactorRGB; ctx->Color.Blend[buf].SrcA = sfactorA; ctx->Color.Blend[buf].DstA = dfactorA; update_uses_dual_src(ctx, buf); ctx->Color._BlendFuncPerBuffer = GL_TRUE; }
/** * Set the separate blend source/dest factors for all draw buffers. * * \param sfactorRGB RGB source factor operator. * \param dfactorRGB RGB destination factor operator. * \param sfactorA alpha source factor operator. * \param dfactorA alpha destination factor operator. */ void GLAPIENTRY _mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { GET_CURRENT_CONTEXT(ctx); const unsigned numBuffers = num_buffers(ctx); unsigned buf; bool changed = false; if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n", _mesa_enum_to_string(sfactorRGB), _mesa_enum_to_string(dfactorRGB), _mesa_enum_to_string(sfactorA), _mesa_enum_to_string(dfactorA)); /* Check if we're really changing any state. If not, return early. */ if (ctx->Color._BlendFuncPerBuffer) { /* Check all per-buffer states */ for (buf = 0; buf < numBuffers; buf++) { if (ctx->Color.Blend[buf].SrcRGB != sfactorRGB || ctx->Color.Blend[buf].DstRGB != dfactorRGB || ctx->Color.Blend[buf].SrcA != sfactorA || ctx->Color.Blend[buf].DstA != dfactorA) { changed = true; break; } } } else { /* only need to check 0th per-buffer state */ if (ctx->Color.Blend[0].SrcRGB != sfactorRGB || ctx->Color.Blend[0].DstRGB != dfactorRGB || ctx->Color.Blend[0].SrcA != sfactorA || ctx->Color.Blend[0].DstA != dfactorA) { changed = true; } } if (!changed) return; if (!validate_blend_factors(ctx, "glBlendFuncSeparate", sfactorRGB, dfactorRGB, sfactorA, dfactorA)) { return; } FLUSH_VERTICES(ctx, _NEW_COLOR); for (buf = 0; buf < numBuffers; buf++) { ctx->Color.Blend[buf].SrcRGB = sfactorRGB; ctx->Color.Blend[buf].DstRGB = dfactorRGB; ctx->Color.Blend[buf].SrcA = sfactorA; ctx->Color.Blend[buf].DstA = dfactorA; } update_uses_dual_src(ctx, 0); for (buf = 1; buf < numBuffers; buf++) { ctx->Color.Blend[buf]._UsesDualSrc = ctx->Color.Blend[0]._UsesDualSrc; } ctx->Color._BlendFuncPerBuffer = GL_FALSE; if (ctx->Driver.BlendFuncSeparate) { ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB, sfactorA, dfactorA); } }