From 3728673bd1b974e54858fbab6ff62d3607b0d3f0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 29 Dec 2009 15:04:03 -0700 Subject: [PATCH] mesa: per-buffer blend enabled flags ctx->Color.BlendEnabled is now a GLbitfield instead of a GLboolean to indicate blend on/off status for each color/draw buffer. This is infrastructure for GL_EXT_draw_buffers2 and OpenGL 3.x New functions include _mesa_EnableIndexed(), _mesa_DisableIndexed(), and _mesa_IsEnabledIndexed(). The enable function corresponds to glEnableIndexedEXT() for GL_EXT_draw_buffers2 or glEnablei() for GL3. Note that there's quite a few tests for ctx->Color.BlendEnabled != 0 in drivers, etc. Those tests can remain as-is since the mask will be 0 or ~0 unless GL_EXT_draw_buffers2 is enabled. --- src/mesa/drivers/common/meta.c | 18 ++++++-- src/mesa/main/attrib.c | 16 ++++++- src/mesa/main/blend.c | 2 +- src/mesa/main/enable.c | 84 ++++++++++++++++++++++++++++++++-- src/mesa/main/enable.h | 12 +++++ src/mesa/main/get.c | 8 ++-- src/mesa/main/get_gen.py | 2 +- src/mesa/main/mtypes.h | 2 +- src/mesa/swrast/s_span.c | 2 +- 9 files changed, 126 insertions(+), 20 deletions(-) diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index cd9075b3936..da2c06677a6 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -107,7 +107,7 @@ struct save_state GLboolean AlphaEnabled; /** META_BLEND */ - GLboolean BlendEnabled; + GLbitfield BlendEnabled; GLboolean ColorLogicOpEnabled; /** META_COLOR_MASK */ @@ -335,8 +335,12 @@ _mesa_meta_begin(GLcontext *ctx, GLbitfield state) if (state & META_BLEND) { save->BlendEnabled = ctx->Color.BlendEnabled; - if (ctx->Color.BlendEnabled) - _mesa_set_enable(ctx, GL_BLEND, GL_FALSE); + if (ctx->Color.BlendEnabled) { + GLuint i; + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { + _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE); + } + } save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled; if (ctx->Color.ColorLogicOpEnabled) _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE); @@ -566,8 +570,12 @@ _mesa_meta_end(GLcontext *ctx) } if (state & META_BLEND) { - if (ctx->Color.BlendEnabled != save->BlendEnabled) - _mesa_set_enable(ctx, GL_BLEND, save->BlendEnabled); + if (ctx->Color.BlendEnabled != save->BlendEnabled) { + GLuint i; + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { + _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1); + } + } if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled) _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled); } diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 246c5521b7d..88ce0a4281b 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -499,7 +499,12 @@ pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable) } TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST); - TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND); + if (ctx->Color.BlendEnabled != enable->Blend) { + GLuint i; + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { + _mesa_set_enablei(ctx, GL_BLEND, i, (enable->Blend >> i) & 1); + } + } for (i=0;idata; _mesa_ClearIndex((GLfloat) color->ClearIndex); _mesa_ClearColor(color->ClearColor[0], @@ -948,7 +954,13 @@ _mesa_PopAttrib(void) } _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled); _mesa_AlphaFunc(color->AlphaFunc, color->AlphaRef); - _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled); + if (ctx->Color.BlendEnabled != color->BlendEnabled) { + GLuint i; + for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { + _mesa_set_enablei(ctx, GL_BLEND, i, + (color->BlendEnabled >> i) & 1); + } + } _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB, color->BlendDstRGB, color->BlendSrcA, diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index 830e3b2e517..5a9d94e12d0 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -564,7 +564,7 @@ void _mesa_init_color( GLcontext * ctx ) ctx->Color.AlphaEnabled = GL_FALSE; ctx->Color.AlphaFunc = GL_ALWAYS; ctx->Color.AlphaRef = 0; - ctx->Color.BlendEnabled = GL_FALSE; + ctx->Color.BlendEnabled = 0x0; ctx->Color.BlendSrcRGB = GL_ONE; ctx->Color.BlendDstRGB = GL_ZERO; ctx->Color.BlendSrcA = GL_ONE; diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 12ce14c5d04..6f9f57f5cb8 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -278,10 +278,13 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state) ctx->Eval.AutoNormal = state; break; case GL_BLEND: - if (ctx->Color.BlendEnabled == state) - return; - FLUSH_VERTICES(ctx, _NEW_COLOR); - ctx->Color.BlendEnabled = state; + { + GLbitfield newEnabled = state * ((1 << ctx->Const.MaxDrawBuffers) - 1); + if (newEnabled != ctx->Color.BlendEnabled) { + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.BlendEnabled = newEnabled; + } + } break; #if FEATURE_userclip case GL_CLIP_PLANE0: @@ -1020,6 +1023,77 @@ _mesa_Disable( GLenum cap ) } + +/** + * Enable/disable an indexed state var. + */ +void +_mesa_set_enablei(GLcontext *ctx, GLenum cap, GLuint index, GLboolean state) +{ + ASSERT(state == 0 || state == 1); + switch (cap) { + case GL_BLEND: + if (index >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", + state ? "glEnableIndexed" : "glDisableIndexed", index); + return; + } + if (((ctx->Color.BlendEnabled >> index) & 1) != state) { + FLUSH_VERTICES(ctx, _NEW_COLOR); + if (state) + ctx->Color.BlendEnabled |= (1 << index); + else + ctx->Color.BlendEnabled &= ~(1 << index); + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "%s(cap=%s)", + state ? "glEnableIndexed" : "glDisableIndexed", + _mesa_lookup_enum_by_nr(cap)); + } +} + + +void GLAPIENTRY +_mesa_DisableIndexed( GLenum cap, GLuint index ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + _mesa_set_enablei(ctx, cap, index, GL_FALSE); +} + + +void GLAPIENTRY +_mesa_EnableIndexed( GLenum cap, GLuint index ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + _mesa_set_enablei(ctx, cap, index, GL_TRUE); +} + + +GLboolean GLAPIENTRY +_mesa_IsEnabledIndexed( GLenum cap, GLuint index ) +{ + GET_CURRENT_CONTEXT(ctx); + switch (cap) { + case GL_BLEND: + if (index >= ctx->Const.MaxDrawBuffers) { + _mesa_error(ctx, GL_INVALID_VALUE, "glIsEnabledIndexed(index=%u)", + index); + return GL_FALSE; + } + return (ctx->Color.BlendEnabled >> index) & 1; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabledIndexed(cap=%s)", + _mesa_lookup_enum_by_nr(cap)); + return GL_FALSE; + } +} + + + + #undef CHECK_EXTENSION #define CHECK_EXTENSION(EXTNAME) \ if (!ctx->Extensions.EXTNAME) { \ @@ -1066,7 +1140,7 @@ _mesa_IsEnabled( GLenum cap ) case GL_AUTO_NORMAL: return ctx->Eval.AutoNormal; case GL_BLEND: - return ctx->Color.BlendEnabled; + return ctx->Color.BlendEnabled & 1; /* return state for buffer[0] */ case GL_CLIP_PLANE0: case GL_CLIP_PLANE1: case GL_CLIP_PLANE2: diff --git a/src/mesa/main/enable.h b/src/mesa/main/enable.h index 25c90b0275a..24e3181a8ba 100644 --- a/src/mesa/main/enable.h +++ b/src/mesa/main/enable.h @@ -47,6 +47,18 @@ _mesa_Enable( GLenum cap ); extern GLboolean GLAPIENTRY _mesa_IsEnabled( GLenum cap ); +extern void +_mesa_set_enablei(GLcontext *ctx, GLenum cap, GLuint index, GLboolean state); + +extern void GLAPIENTRY +_mesa_DisableIndexed( GLenum cap, GLuint index ); + +extern void GLAPIENTRY +_mesa_EnableIndexed( GLenum cap, GLuint index ); + +extern GLboolean GLAPIENTRY +_mesa_IsEnabledIndexed( GLenum cap, GLuint index ); + extern void GLAPIENTRY _mesa_EnableClientState( GLenum cap ); diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 3d32649bade..07507414d70 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -132,7 +132,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) params[0] = INT_TO_BOOLEAN(ctx->DrawBuffer->Visual.numAuxBuffers); break; case GL_BLEND: - params[0] = ctx->Color.BlendEnabled; + params[0] = (ctx->Color.BlendEnabled & 1); break; case GL_BLEND_DST: params[0] = ENUM_TO_BOOLEAN(ctx->Color.BlendDstRGB); @@ -1967,7 +1967,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) params[0] = (GLfloat)(ctx->DrawBuffer->Visual.numAuxBuffers); break; case GL_BLEND: - params[0] = BOOLEAN_TO_FLOAT(ctx->Color.BlendEnabled); + params[0] = BOOLEAN_TO_FLOAT((ctx->Color.BlendEnabled & 1)); break; case GL_BLEND_DST: params[0] = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB); @@ -3802,7 +3802,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) params[0] = ctx->DrawBuffer->Visual.numAuxBuffers; break; case GL_BLEND: - params[0] = BOOLEAN_TO_INT(ctx->Color.BlendEnabled); + params[0] = BOOLEAN_TO_INT((ctx->Color.BlendEnabled & 1)); break; case GL_BLEND_DST: params[0] = ENUM_TO_INT(ctx->Color.BlendDstRGB); @@ -5638,7 +5638,7 @@ _mesa_GetInteger64v( GLenum pname, GLint64 *params ) params[0] = (GLint64)(ctx->DrawBuffer->Visual.numAuxBuffers); break; case GL_BLEND: - params[0] = BOOLEAN_TO_INT64(ctx->Color.BlendEnabled); + params[0] = BOOLEAN_TO_INT64((ctx->Color.BlendEnabled & 1)); break; case GL_BLEND_DST: params[0] = ENUM_TO_INT64(ctx->Color.BlendDstRGB); diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index 01170a42a72..5aff9d3544e 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -82,7 +82,7 @@ StateVars = [ ( "GL_AUTO_NORMAL", GLboolean, ["ctx->Eval.AutoNormal"], "", None ), ( "GL_AUX_BUFFERS", GLint, ["ctx->DrawBuffer->Visual.numAuxBuffers"], "", None ), - ( "GL_BLEND", GLboolean, ["ctx->Color.BlendEnabled"], "", None ), + ( "GL_BLEND", GLboolean, ["(ctx->Color.BlendEnabled & 1)"], "", None ), ( "GL_BLEND_DST", GLenum, ["ctx->Color.BlendDstRGB"], "", None ), ( "GL_BLEND_SRC", GLenum, ["ctx->Color.BlendSrcRGB"], "", None ), ( "GL_BLEND_SRC_RGB_EXT", GLenum, ["ctx->Color.BlendSrcRGB"], "", None ), diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index b52c84b491a..170c35b11c6 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -581,7 +581,7 @@ struct gl_colorbuffer_attrib * \name Blending */ /*@{*/ - GLboolean BlendEnabled; /**< Blending enabled flag */ + GLbitfield BlendEnabled; /**< Per-buffer blend enable flags */ GLenum BlendSrcRGB; /**< Blending source operator */ GLenum BlendDstRGB; /**< Blending destination operator */ GLenum BlendSrcA; /**< GL_INGR_blend_func_separate */ diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index d36c8132f63..00de13d4954 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1479,7 +1479,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) if (ctx->Color._LogicOpEnabled) { _swrast_logicop_rgba_span(ctx, rb, span); } - else if (ctx->Color.BlendEnabled) { + else if ((ctx->Color.BlendEnabled >> buf) & 1) { _swrast_blend_span(ctx, rb, span); } -- 2.30.2