summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVladimir Dergachev <volodya@freedesktop.org>2005-01-04 20:25:11 +0000
committerVladimir Dergachev <volodya@freedesktop.org>2005-01-04 20:25:11 +0000
commit6b185aaedfacf3cc435d575585cc5f2e029bece6 (patch)
tree2844dfa281566efc3f36065f347c964d9542c1e3 /src
parent55ee1daaf929b9dca436a238f87715caec184445 (diff)
Port code from r200 that implements color blending. Seems to work.
This can be tested with lesson19 from NeHe. This has also shown that the alpha code does not work - we pick up a red tint for transparent pixels somewhere.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.c7
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c282
3 files changed, 288 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
index 0b876d576e..b4b1aebc4d 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
@@ -109,6 +109,13 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer)
r300->hw.vpt.cmd[R300_VPT_ZSCALE] = r300PackFloat32(1.0);
r300->hw.vpt.cmd[R300_VPT_ZOFFSET] = r300PackFloat32(0.0);
+ R300_STATECHANGE(r300, at);
+ r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
+
+ R300_STATECHANGE(r300, bld);
+ r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
+ r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
+
R300_STATECHANGE(r300, cb);
r300->hw.cb.cmd[R300_CB_OFFSET] = cboffset;
r300->hw.cb.cmd[R300_CB_PITCH] = cbpitch | R300_COLOR_UNKNOWN_22_23;
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index b122927e1f..aad8570378 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -585,7 +585,7 @@ static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
#if 0 /* This should work now.. */
FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
#endif
- FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
+ //FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG
FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH
FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index f97af907a8..f67025494f 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -100,6 +100,273 @@ static void r300AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref)
rmesa->hw.at.cmd[R300_AT_ALPHA_TEST] = pp_misc;
}
+static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4])
+{
+ GLubyte color[4];
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ fprintf(stderr, "%s:%s is not implemented yet. Fixme !\n", __FILE__, __FUNCTION__);
+ #if 0
+ 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->radeon.radeonScreen->drmSupportsBlendColor)
+ rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] =
+ radeonPackColor(4, color[0], color[1], color[2], color[3]);
+ #endif
+}
+
+/**
+ * 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 r300_set_blend_state(GLcontext * ctx)
+{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ #if 0
+ GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
+ ~(R300_ROP_ENABLE | R300_ALPHA_BLEND_ENABLE |
+ R300_SEPARATE_ALPHA_ENABLE);
+ #endif
+
+ 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;
+
+ R300_STATECHANGE(rmesa, bld);
+
+ if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
+ if (ctx->Color._LogicOpEnabled) {
+ #if 0
+ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
+ cntl | R300_ROP_ENABLE;
+ #endif
+ rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqn | func;
+ rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func;
+ return;
+ } else if (ctx->Color.BlendEnabled) {
+ #if 0
+ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
+ cntl | R300_ALPHA_BLEND_ENABLE |
+ R300_SEPARATE_ALPHA_ENABLE;
+ #endif
+ } else {
+ #if 0
+ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
+ #endif
+ rmesa->hw.bld.cmd[R300_BLD_ABLEND] = eqn | func;
+ rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func;
+ return;
+ }
+ } else {
+ if (ctx->Color._LogicOpEnabled) {
+ #if 0
+ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
+ cntl | R300_ROP_ENABLE;
+ rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
+ #endif
+ return;
+ } else if (ctx->Color.BlendEnabled) {
+ #if 0
+ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =
+ cntl | R300_ALPHA_BLEND_ENABLE;
+ #endif
+ } else {
+ #if 0
+ rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
+ rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
+ #endif
+ 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:
+ eqn = R300_COMB_FCN_ADD_CLAMP;
+ break;
+
+ case GL_FUNC_SUBTRACT:
+ eqn = R300_COMB_FCN_SUB_CLAMP;
+ break;
+
+ case GL_FUNC_REVERSE_SUBTRACT:
+ eqn = R200_COMB_FCN_RSUB_CLAMP;
+ break;
+
+ 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_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:
+ fprintf(stderr,
+ "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
+ __func__, __LINE__, ctx->Color.BlendEquationRGB);
+ return;
+ }
+
+ if (!rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
+ #if 0
+ rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
+ #endif
+ 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 = R300_COMB_FCN_ADD_CLAMP;
+ break;
+
+ case GL_FUNC_SUBTRACT:
+ eqnA = R300_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.bld.cmd[R300_BLD_ABLEND] = eqnA | funcA;
+ rmesa->hw.bld.cmd[R300_BLD_CBLEND] = eqn | func ;
+ if(rmesa->hw.bld.cmd[R300_BLD_ABLEND] == rmesa->hw.bld.cmd[R300_BLD_CBLEND]){
+ rmesa->hw.bld.cmd[R300_BLD_CBLEND] |= R300_BLEND_UNKNOWN | R300_BLEND_ENABLE | R300_BLEND_NO_SEPARATE;
+ } else {
+ rmesa->hw.bld.cmd[R300_BLD_CBLEND] |= R300_BLEND_UNKNOWN | R300_BLEND_ENABLE;
+ }
+
+}
+
+static void r300BlendEquationSeparate(GLcontext * ctx,
+ GLenum modeRGB, GLenum modeA)
+{
+ r300_set_blend_state(ctx);
+}
+
+static void r300BlendFuncSeparate(GLcontext * ctx,
+ GLenum sfactorRGB, GLenum dfactorRGB,
+ GLenum sfactorA, GLenum dfactorA)
+{
+ r300_set_blend_state(ctx);
+}
+
/**
* Update our tracked culling state based on Mesa's state.
*/
@@ -524,7 +791,7 @@ void r300_setup_textures(GLcontext *ctx)
exit(-1);
}
for(i=0;i<mtu;i++){
- if(ctx->Texture.Unit[i].Enabled!=NULL){
+ if(ctx->Texture.Unit[i].Enabled){
t=r300->state.texture.unit[i].texobj;
r300->state.texture.tc_count++;
if(t==NULL){
@@ -668,6 +935,10 @@ void r300ResetHwState(r300ContextPtr r300)
r300UpdateTextureState(ctx);
r300_setup_textures(ctx);
r300_setup_rs_unit(ctx);
+
+
+ r300_set_blend_state(ctx);
+ r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
//BEGIN: TODO
r300->hw.unk2080.cmd[1] = 0x0030045A;
@@ -813,14 +1084,18 @@ void r300ResetHwState(r300ContextPtr r300)
r300->hw.unk4BC8.cmd[2] = 0;
r300->hw.unk4BC8.cmd[3] = 0;
+ #if 0
r300->hw.at.cmd[R300_AT_ALPHA_TEST] = 0;
+ #endif
r300->hw.unk4BD8.cmd[1] = 0;
r300->hw.unk4E00.cmd[1] = 0;
+ #if 0
r300->hw.bld.cmd[R300_BLD_CBLEND] = 0;
r300->hw.bld.cmd[R300_BLD_ABLEND] = 0;
+ #endif
r300->hw.unk4E10.cmd[1] = 0;
r300->hw.unk4E10.cmd[2] = 0;
@@ -937,7 +1212,10 @@ void r300InitStateFuncs(struct dd_function_table* functions)
radeonInitStateFuncs(functions);
functions->UpdateState = r300InvalidateState;
- functions->AlphaFunc = r300AlphaFunc;
+ //functions->AlphaFunc = r300AlphaFunc;
+ functions->BlendColor = r300BlendColor;
+ functions->BlendEquationSeparate = r300BlendEquationSeparate;
+ functions->BlendFuncSeparate = r300BlendFuncSeparate;
functions->Enable = r300Enable;
functions->ColorMask = r300ColorMask;
functions->DepthFunc = r300DepthFunc;