From b9cbd5272452dcaae1d1b2462ed3001d64dc55e8 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 14 May 2004 13:01:08 +0000 Subject: Fix GL_MIN and GL_MAX blend equations (set blend factors accordingly). Fix errors when blending is disabled (set blend equation and function to default values). --- src/mesa/drivers/dri/r200/r200_reg.h | 53 +++--- src/mesa/drivers/dri/r200/r200_state.c | 240 +++++++++++++--------------- src/mesa/drivers/dri/r200/r200_state_init.c | 4 +- 3 files changed, 135 insertions(+), 162 deletions(-) diff --git a/src/mesa/drivers/dri/r200/r200_reg.h b/src/mesa/drivers/dri/r200/r200_reg.h index 8e9126342f..685fc5c031 100644 --- a/src/mesa/drivers/dri/r200/r200_reg.h +++ b/src/mesa/drivers/dri/r200/r200_reg.h @@ -69,39 +69,26 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R200_COMB_FCN_MAX (5 << 12) #define R200_COMB_FCN_RSUB_CLAMP (6 << 12) #define R200_COMB_FCN_RSUB_NOCLAMP (7 << 12) -#define R200_SRC_BLEND_GL_ZERO (32 << 16) -#define R200_SRC_BLEND_GL_ONE (33 << 16) -#define R200_SRC_BLEND_GL_SRC_COLOR (34 << 16) -#define R200_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16) -#define R200_SRC_BLEND_GL_DST_COLOR (36 << 16) -#define R200_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16) -#define R200_SRC_BLEND_GL_SRC_ALPHA (38 << 16) -#define R200_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16) -#define R200_SRC_BLEND_GL_DST_ALPHA (40 << 16) -#define R200_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16) -#define R200_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16) -#define R200_SRC_BLEND_GL_CONST_COLOR (43 << 16) -#define R200_SRC_BLEND_GL_ONE_MINUS_CONST_COLOR (44 << 16) -#define R200_SRC_BLEND_GL_CONST_ALPHA (45 << 16) -#define R200_SRC_BLEND_GL_ONE_MINUS_CONST_ALPHA (46 << 16) -#define R200_SRC_BLEND_MASK (63 << 16) -#define R200_DST_BLEND_GL_ZERO (32 << 24) -#define R200_DST_BLEND_GL_ONE (33 << 24) -#define R200_DST_BLEND_GL_SRC_COLOR (34 << 24) -#define R200_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24) -#define R200_DST_BLEND_GL_DST_COLOR (36 << 24) -#define R200_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24) -#define R200_DST_BLEND_GL_SRC_ALPHA (38 << 24) -#define R200_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24) -#define R200_DST_BLEND_GL_DST_ALPHA (40 << 24) -#define R200_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24) -#define R200_DST_BLEND_GL_CONST_COLOR (43 << 24) -#define R200_DST_BLEND_GL_ONE_MINUS_CONST_COLOR (44 << 24) -#define R200_DST_BLEND_GL_CONST_ALPHA (45 << 24) -#define R200_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA (46 << 24) -#define R200_DST_BLEND_MASK (63 << 24) -#define R200_RB3D_DEPTHOFFSET 0x1c24 -#define R200_RB3D_DEPTHPITCH 0x1c28 +#define R200_BLEND_GL_ZERO (32) +#define R200_BLEND_GL_ONE (33) +#define R200_BLEND_GL_SRC_COLOR (34) +#define R200_BLEND_GL_ONE_MINUS_SRC_COLOR (35) +#define R200_BLEND_GL_DST_COLOR (36) +#define R200_BLEND_GL_ONE_MINUS_DST_COLOR (37) +#define R200_BLEND_GL_SRC_ALPHA (38) +#define R200_BLEND_GL_ONE_MINUS_SRC_ALPHA (39) +#define R200_BLEND_GL_DST_ALPHA (40) +#define R200_BLEND_GL_ONE_MINUS_DST_ALPHA (41) +#define R200_BLEND_GL_SRC_ALPHA_SATURATE (42) /* src factor only */ +#define R200_BLEND_GL_CONST_COLOR (43) +#define R200_BLEND_GL_ONE_MINUS_CONST_COLOR (44) +#define R200_BLEND_GL_CONST_ALPHA (45) +#define R200_BLEND_GL_ONE_MINUS_CONST_ALPHA (46) +#define R200_BLEND_MASK (63) +#define R200_SRC_BLEND_SHIFT (16) +#define R200_DST_BLEND_SHIFT (24) +#define R200_RB3D_DEPTHOFFSET 0x1c24 +#define R200_RB3D_DEPTHPITCH 0x1c28 #define R200_DEPTHPITCH_MASK 0x00001ff8 #define R200_DEPTH_ENDIAN_NO_SWAP (0 << 18) #define R200_DEPTH_ENDIAN_WORD_SWAP (1 << 18) diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 1dd352a53d..70ce8b4e0d 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -104,156 +104,160 @@ static void r200AlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref ) rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc; } -static void r200BlendEquationSeparate( GLcontext *ctx, - GLenum modeRGB, GLenum modeA ) -{ - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~R200_COMB_FCN_MASK; - - assert( modeRGB == modeA ); - - switch ( modeRGB ) { - case GL_FUNC_ADD: - case GL_LOGIC_OP: - b |= R200_COMB_FCN_ADD_CLAMP; - break; - - case GL_FUNC_SUBTRACT: - b |= R200_COMB_FCN_SUB_CLAMP; - break; - - case GL_FUNC_REVERSE_SUBTRACT: - b |= R200_COMB_FCN_RSUB_CLAMP; - break; - - case GL_MIN: - b |= R200_COMB_FCN_MIN; - break; - - case GL_MAX: - b |= R200_COMB_FCN_MAX; - break; - - default: - break; - } - - R200_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b; - if ( ctx->Color._LogicOpEnabled ) { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_ROP_ENABLE; - } else { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ROP_ENABLE; - } -} - -static void r200BlendFuncSeparate( GLcontext *ctx, - GLenum sfactorRGB, GLenum dfactorRGB, - GLenum sfactorA, GLenum dfactorA ) +/** + * Calculate the hardware blend factor setting. This same function is used + * for source and destination of both alpha and RGB. + * + * \returns + * The hardware register value for the specified blend factor. This value + * will need to be shifted into the correct position for either source or + * destination factor. + * + * \todo + * Since the two cases where source and destination are handled differently + * are essentially error cases, they should never happen. Determine if these + * cases can be removed. + */ +static int blend_factor( GLenum factor, GLboolean is_src ) { - r200ContextPtr rmesa = R200_CONTEXT(ctx); - GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & - ~(R200_SRC_BLEND_MASK | R200_DST_BLEND_MASK); + int func; - switch ( ctx->Color.BlendSrcRGB ) { + switch ( factor ) { case GL_ZERO: - b |= R200_SRC_BLEND_GL_ZERO; + func = R200_BLEND_GL_ZERO; break; case GL_ONE: - b |= R200_SRC_BLEND_GL_ONE; + func = R200_BLEND_GL_ONE; break; case GL_DST_COLOR: - b |= R200_SRC_BLEND_GL_DST_COLOR; + func = R200_BLEND_GL_DST_COLOR; break; case GL_ONE_MINUS_DST_COLOR: - b |= R200_SRC_BLEND_GL_ONE_MINUS_DST_COLOR; + func = R200_BLEND_GL_ONE_MINUS_DST_COLOR; break; case GL_SRC_COLOR: - b |= R200_SRC_BLEND_GL_SRC_COLOR; + func = R200_BLEND_GL_SRC_COLOR; break; case GL_ONE_MINUS_SRC_COLOR: - b |= R200_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR; + func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR; break; case GL_SRC_ALPHA: - b |= R200_SRC_BLEND_GL_SRC_ALPHA; + func = R200_BLEND_GL_SRC_ALPHA; break; case GL_ONE_MINUS_SRC_ALPHA: - b |= R200_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA; + func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA; break; case GL_DST_ALPHA: - b |= R200_SRC_BLEND_GL_DST_ALPHA; + func = R200_BLEND_GL_DST_ALPHA; break; case GL_ONE_MINUS_DST_ALPHA: - b |= R200_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA; + func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA; break; case GL_SRC_ALPHA_SATURATE: - b |= R200_SRC_BLEND_GL_SRC_ALPHA_SATURATE; + func = (is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE : R200_BLEND_GL_ZERO; break; case GL_CONSTANT_COLOR: - b |= R200_SRC_BLEND_GL_CONST_COLOR; + func = R200_BLEND_GL_CONST_COLOR; break; case GL_ONE_MINUS_CONSTANT_COLOR: - b |= R200_SRC_BLEND_GL_ONE_MINUS_CONST_COLOR; + func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR; break; case GL_CONSTANT_ALPHA: - b |= R200_SRC_BLEND_GL_CONST_ALPHA; + func = R200_BLEND_GL_CONST_ALPHA; break; case GL_ONE_MINUS_CONSTANT_ALPHA: - b |= R200_SRC_BLEND_GL_ONE_MINUS_CONST_ALPHA; + func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA; break; default: - break; + func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO; } + return func; +} - switch ( ctx->Color.BlendDstRGB ) { - case GL_ZERO: - b |= R200_DST_BLEND_GL_ZERO; - break; - case GL_ONE: - b |= R200_DST_BLEND_GL_ONE; - break; - case GL_SRC_COLOR: - b |= R200_DST_BLEND_GL_SRC_COLOR; - break; - case GL_ONE_MINUS_SRC_COLOR: - b |= R200_DST_BLEND_GL_ONE_MINUS_SRC_COLOR; - break; - case GL_SRC_ALPHA: - b |= R200_DST_BLEND_GL_SRC_ALPHA; - break; - case GL_ONE_MINUS_SRC_ALPHA: - b |= R200_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA; - break; - case GL_DST_COLOR: - b |= R200_DST_BLEND_GL_DST_COLOR; - break; - case GL_ONE_MINUS_DST_COLOR: - b |= R200_DST_BLEND_GL_ONE_MINUS_DST_COLOR; - break; - case GL_DST_ALPHA: - b |= R200_DST_BLEND_GL_DST_ALPHA; - break; - case GL_ONE_MINUS_DST_ALPHA: - b |= R200_DST_BLEND_GL_ONE_MINUS_DST_ALPHA; +/** + * Sets both the blend equation and the blend function. + * 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. + * Also, make sure that blend function and blend equation are set to their default + * value if color blending is not enabled, since at least blend equations GL_MIN + * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for + * unknown reasons. + */ +static void r200_set_blend_state( GLcontext * ctx ) +{ + r200ContextPtr rmesa = R200_CONTEXT(ctx); + GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] & + ~(R200_ROP_ENABLE | R200_ALPHA_BLEND_ENABLE); + + int func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) | + (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT); + int eqn = R200_COMB_FCN_ADD_CLAMP; + + R200_STATECHANGE( rmesa, ctx ); + + if (ctx->Color._LogicOpEnabled) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl | R200_ROP_ENABLE; + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func; + return; + } else if (ctx->Color.BlendEnabled) { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl | R200_ALPHA_BLEND_ENABLE; + } + else { + rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl; + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func; + return; + } + + func = (blend_factor( ctx->Color.BlendSrcRGB, GL_TRUE ) << R200_SRC_BLEND_SHIFT) | + (blend_factor( ctx->Color.BlendDstRGB, GL_FALSE ) << R200_DST_BLEND_SHIFT); + + switch(ctx->Color.BlendEquationRGB) { + case GL_FUNC_ADD: + case GL_LOGIC_OP: + eqn = R200_COMB_FCN_ADD_CLAMP; break; - case GL_CONSTANT_COLOR: - b |= R200_DST_BLEND_GL_CONST_COLOR; + + case GL_FUNC_SUBTRACT: + eqn = R200_COMB_FCN_SUB_CLAMP; break; - case GL_ONE_MINUS_CONSTANT_COLOR: - b |= R200_DST_BLEND_GL_ONE_MINUS_CONST_COLOR; + + case GL_FUNC_REVERSE_SUBTRACT: + eqn = R200_COMB_FCN_RSUB_CLAMP; break; - case GL_CONSTANT_ALPHA: - b |= R200_DST_BLEND_GL_CONST_ALPHA; + + case GL_MIN: + eqn = R200_COMB_FCN_MIN; + func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) | + (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT); break; - case GL_ONE_MINUS_CONSTANT_ALPHA: - b |= R200_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA; + + case GL_MAX: + eqn = R200_COMB_FCN_MAX; + func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) | + (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT); break; + default: - break; + fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n", + __func__, __LINE__, ctx->Color.BlendEquationRGB ); + return; } - R200_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b; + rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func; +} + +static void r200BlendEquationSeparate( GLcontext *ctx, + GLenum modeRGB, GLenum modeA ) +{ + r200_set_blend_state( ctx ); +} + +static void r200BlendFuncSeparate( GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) +{ + r200_set_blend_state( ctx ); } @@ -1738,17 +1742,8 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) break; case GL_BLEND: - R200_STATECHANGE( rmesa, ctx ); - if (state) { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_ALPHA_BLEND_ENABLE; - } else { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ALPHA_BLEND_ENABLE; - } - if ( ctx->Color._LogicOpEnabled ) { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_ROP_ENABLE; - } else { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ROP_ENABLE; - } + case GL_COLOR_LOGIC_OP: + r200_set_blend_state( ctx ); break; case GL_CLIP_PLANE0: @@ -1864,15 +1859,6 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) } break; - case GL_COLOR_LOGIC_OP: - R200_STATECHANGE( rmesa, ctx ); - if ( ctx->Color._LogicOpEnabled ) { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= R200_ROP_ENABLE; - } else { - rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_ROP_ENABLE; - } - break; - case GL_NORMALIZE: R200_STATECHANGE( rmesa, tcl ); if ( state ) { diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index d9896c99db..4e073f2fc5 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -367,8 +367,8 @@ void r200InitState( r200ContextPtr rmesa ) rmesa->hw.ctx.cmd[CTX_RE_SOLID_COLOR] = 0x00000000; rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = (R200_COMB_FCN_ADD_CLAMP | - R200_SRC_BLEND_GL_ONE | - R200_DST_BLEND_GL_ZERO ); + (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) | + (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT)); rmesa->hw.ctx.cmd[CTX_RB3D_DEPTHOFFSET] = rmesa->r200Screen->depthOffset + rmesa->r200Screen->fbLocation; -- cgit v1.2.3