summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c5
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.h7
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c99
-rw-r--r--src/mesa/drivers/dri/r200/r200_state_init.c21
4 files changed, 115 insertions, 17 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index 95c7c32362..235522cfd6 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -129,7 +129,6 @@ static const char * const card_extensions[] =
"GL_ARB_texture_env_dot3",
"GL_ARB_texture_mirrored_repeat",
"GL_ARB_vertex_buffer_object",
- "GL_EXT_blend_logic_op",
"GL_EXT_blend_minmax",
"GL_EXT_blend_subtract",
"GL_EXT_secondary_color",
@@ -402,6 +401,10 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
driInitExtensions( ctx, card_extensions, GL_TRUE );
if (rmesa->r200Screen->drmSupportsCubeMaps)
_mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
+ if (rmesa->r200Screen->drmSupportsBlendColor) {
+ _mesa_enable_extension( ctx, "GL_EXT_blend_equation_separate" );
+ _mesa_enable_extension( ctx, "GL_EXT_blend_func_separate" );
+ }
#if 0
r200InitDriverFuncs( ctx );
diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h
index 63d688718c..aa3e8dad91 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -213,7 +213,12 @@ struct r200_state_atom {
#define CTX_RB3D_COLOROFFSET 11
#define CTX_CMD_2 12 /* why */
#define CTX_RB3D_COLORPITCH 13 /* why */
-#define CTX_STATE_SIZE 14
+#define CTX_STATE_SIZE_OLDDRM 14
+#define CTX_CMD_3 14
+#define CTX_RB3D_BLENDCOLOR 15
+#define CTX_RB3D_ABLENDCNTL 16
+#define CTX_RB3D_CBLENDCNTL 17
+#define CTX_STATE_SIZE_NEWDRM 18
#define SET_CMD_0 0
#define SET_SE_CNTL 1
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index 70ce8b4e0d..347ee3ca40 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -104,6 +104,19 @@ static void r200AlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
}
+static void r200BlendColor( GLcontext *ctx, const GLfloat cf[4] )
+{
+ GLubyte color[4];
+ r200ContextPtr rmesa = R200_CONTEXT(ctx);
+ R200_STATECHANGE( rmesa, ctx );
+ CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]);
+ CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]);
+ CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]);
+ CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]);
+ if (rmesa->r200Screen->drmSupportsBlendColor)
+ rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] = r200PackColor( 4, color[0], color[1], color[2], color[3] );
+}
+
/**
* Calculate the hardware blend factor setting. This same function is used
* for source and destination of both alpha and RGB.
@@ -188,25 +201,46 @@ 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);
+ ~(R200_ROP_ENABLE | R200_ALPHA_BLEND_ENABLE | R200_SEPARATE_ALPHA_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;
+ int funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
+ (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
+ int eqnA = 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;
+ if (rmesa->r200Screen->drmSupportsBlendColor) {
+ if (ctx->Color._LogicOpEnabled) {
+ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl | R200_ROP_ENABLE;
+ rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func;
+ rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
+ return;
+ } else if (ctx->Color.BlendEnabled) {
+ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl | R200_ALPHA_BLEND_ENABLE | R200_SEPARATE_ALPHA_ENABLE;
+ }
+ else {
+ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
+ rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func;
+ rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
+ return;
+ }
}
else {
- rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
- rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
- return;
+ 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) |
@@ -214,7 +248,6 @@ static void r200_set_blend_state( GLcontext * ctx )
switch(ctx->Color.BlendEquationRGB) {
case GL_FUNC_ADD:
- case GL_LOGIC_OP:
eqn = R200_COMB_FCN_ADD_CLAMP;
break;
@@ -244,7 +277,48 @@ static void r200_set_blend_state( GLcontext * ctx )
return;
}
- rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
+ if (!rmesa->r200Screen->drmSupportsBlendColor) {
+ rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
+ return;
+ }
+
+ funcA = (blend_factor( ctx->Color.BlendSrcA, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
+ (blend_factor( ctx->Color.BlendDstA, GL_FALSE ) << R200_DST_BLEND_SHIFT);
+
+ switch(ctx->Color.BlendEquationA) {
+ case GL_FUNC_ADD:
+ eqnA = R200_COMB_FCN_ADD_CLAMP;
+ break;
+
+ case GL_FUNC_SUBTRACT:
+ eqnA = R200_COMB_FCN_SUB_CLAMP;
+ break;
+
+ case GL_FUNC_REVERSE_SUBTRACT:
+ eqnA = R200_COMB_FCN_RSUB_CLAMP;
+ break;
+
+ case GL_MIN:
+ eqnA = R200_COMB_FCN_MIN;
+ funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
+ (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
+ break;
+
+ case GL_MAX:
+ eqnA = R200_COMB_FCN_MAX;
+ funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
+ (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
+ break;
+
+ default:
+ fprintf( stderr, "[%s:%u] Invalid A blend equation (0x%04x).\n",
+ __func__, __LINE__, ctx->Color.BlendEquationA );
+ return;
+ }
+
+ rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqnA | funcA;
+ rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
+
}
static void r200BlendEquationSeparate( GLcontext *ctx,
@@ -2208,6 +2282,7 @@ void r200InitStateFuncs( struct dd_function_table *functions )
functions->ReadBuffer = r200ReadBuffer;
functions->AlphaFunc = r200AlphaFunc;
+ functions->BlendColor = r200BlendColor;
functions->BlendEquationSeparate = r200BlendEquationSeparate;
functions->BlendFuncSeparate = r200BlendFuncSeparate;
functions->ClearColor = r200ClearColor;
diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c
index 4e073f2fc5..08675cfbf9 100644
--- a/src/mesa/drivers/dri/r200/r200_state_init.c
+++ b/src/mesa/drivers/dri/r200/r200_state_init.c
@@ -218,7 +218,10 @@ void r200InitState( r200ContextPtr rmesa )
/* Allocate state buffers:
*/
- ALLOC_STATE( ctx, always, CTX_STATE_SIZE, "CTX/context", 0 );
+ if (rmesa->r200Screen->drmSupportsBlendColor)
+ ALLOC_STATE( ctx, always, CTX_STATE_SIZE_NEWDRM, "CTX/context", 0 );
+ else
+ ALLOC_STATE( ctx, always, CTX_STATE_SIZE_OLDDRM, "CTX/context", 0 );
ALLOC_STATE( set, always, SET_STATE_SIZE, "SET/setup", 0 );
ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 );
ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 );
@@ -280,6 +283,8 @@ void r200InitState( r200ContextPtr rmesa )
rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(RADEON_EMIT_PP_MISC);
rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(RADEON_EMIT_PP_CNTL);
rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(RADEON_EMIT_RB3D_COLORPITCH);
+ if (rmesa->r200Screen->drmSupportsBlendColor)
+ rmesa->hw.ctx.cmd[CTX_CMD_3] = cmdpkt(R200_EMIT_RB3D_BLENDCOLOR);
rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(RADEON_EMIT_RE_LINE_PATTERN);
rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(RADEON_EMIT_SE_LINE_WIDTH);
rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(RADEON_EMIT_RB3D_STENCILREFMASK);
@@ -367,8 +372,18 @@ 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_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
- (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT));
+ (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
+ (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT));
+
+ if (rmesa->r200Screen->drmSupportsBlendColor) {
+ rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] = 0x00000000;
+ rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = (R200_COMB_FCN_ADD_CLAMP |
+ (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
+ (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT));
+ rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = (R200_COMB_FCN_ADD_CLAMP |
+ (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;