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).

This commit is contained in:
Roland Scheidegger 2004-05-14 13:01:08 +00:00
parent d359f96a18
commit b9cbd52724
3 changed files with 149 additions and 176 deletions

View File

@ -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)

View File

@ -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 )
/**
* 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 )
{
int func;
switch ( factor ) {
case GL_ZERO:
func = R200_BLEND_GL_ZERO;
break;
case GL_ONE:
func = R200_BLEND_GL_ONE;
break;
case GL_DST_COLOR:
func = R200_BLEND_GL_DST_COLOR;
break;
case GL_ONE_MINUS_DST_COLOR:
func = R200_BLEND_GL_ONE_MINUS_DST_COLOR;
break;
case GL_SRC_COLOR:
func = R200_BLEND_GL_SRC_COLOR;
break;
case GL_ONE_MINUS_SRC_COLOR:
func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR;
break;
case GL_SRC_ALPHA:
func = R200_BLEND_GL_SRC_ALPHA;
break;
case GL_ONE_MINUS_SRC_ALPHA:
func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA;
break;
case GL_DST_ALPHA:
func = R200_BLEND_GL_DST_ALPHA;
break;
case GL_ONE_MINUS_DST_ALPHA:
func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA;
break;
case GL_SRC_ALPHA_SATURATE:
func = (is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE : R200_BLEND_GL_ZERO;
break;
case GL_CONSTANT_COLOR:
func = R200_BLEND_GL_CONST_COLOR;
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR;
break;
case GL_CONSTANT_ALPHA:
func = R200_BLEND_GL_CONST_ALPHA;
break;
case GL_ONE_MINUS_CONSTANT_ALPHA:
func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA;
break;
default:
func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO;
}
return func;
}
/**
* 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 b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~R200_COMB_FCN_MASK;
GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
~(R200_ROP_ENABLE | R200_ALPHA_BLEND_ENABLE);
assert( modeRGB == modeA );
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;
switch ( modeRGB ) {
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:
b |= R200_COMB_FCN_ADD_CLAMP;
eqn = R200_COMB_FCN_ADD_CLAMP;
break;
case GL_FUNC_SUBTRACT:
b |= R200_COMB_FCN_SUB_CLAMP;
eqn = R200_COMB_FCN_SUB_CLAMP;
break;
case GL_FUNC_REVERSE_SUBTRACT:
b |= R200_COMB_FCN_RSUB_CLAMP;
eqn = R200_COMB_FCN_RSUB_CLAMP;
break;
case GL_MIN:
b |= R200_COMB_FCN_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_MAX:
b |= R200_COMB_FCN_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;
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;
}
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 )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] &
~(R200_SRC_BLEND_MASK | R200_DST_BLEND_MASK);
switch ( ctx->Color.BlendSrcRGB ) {
case GL_ZERO:
b |= R200_SRC_BLEND_GL_ZERO;
break;
case GL_ONE:
b |= R200_SRC_BLEND_GL_ONE;
break;
case GL_DST_COLOR:
b |= R200_SRC_BLEND_GL_DST_COLOR;
break;
case GL_ONE_MINUS_DST_COLOR:
b |= R200_SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
break;
case GL_SRC_COLOR:
b |= R200_SRC_BLEND_GL_SRC_COLOR;
break;
case GL_ONE_MINUS_SRC_COLOR:
b |= R200_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR;
break;
case GL_SRC_ALPHA:
b |= R200_SRC_BLEND_GL_SRC_ALPHA;
break;
case GL_ONE_MINUS_SRC_ALPHA:
b |= R200_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA;
break;
case GL_DST_ALPHA:
b |= R200_SRC_BLEND_GL_DST_ALPHA;
break;
case GL_ONE_MINUS_DST_ALPHA:
b |= R200_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA;
break;
case GL_SRC_ALPHA_SATURATE:
b |= R200_SRC_BLEND_GL_SRC_ALPHA_SATURATE;
break;
case GL_CONSTANT_COLOR:
b |= R200_SRC_BLEND_GL_CONST_COLOR;
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
b |= R200_SRC_BLEND_GL_ONE_MINUS_CONST_COLOR;
break;
case GL_CONSTANT_ALPHA:
b |= R200_SRC_BLEND_GL_CONST_ALPHA;
break;
case GL_ONE_MINUS_CONSTANT_ALPHA:
b |= R200_SRC_BLEND_GL_ONE_MINUS_CONST_ALPHA;
break;
default:
break;
}
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;
break;
case GL_CONSTANT_COLOR:
b |= R200_DST_BLEND_GL_CONST_COLOR;
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
b |= R200_DST_BLEND_GL_ONE_MINUS_CONST_COLOR;
break;
case GL_CONSTANT_ALPHA:
b |= R200_DST_BLEND_GL_CONST_ALPHA;
break;
case GL_ONE_MINUS_CONSTANT_ALPHA:
b |= R200_DST_BLEND_GL_ONE_MINUS_CONST_ALPHA;
break;
default:
break;
}
R200_STATECHANGE( rmesa, ctx );
rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
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 ) {

View File

@ -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;