summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolai Haehnle <nhaehnle@gmail.com>2008-07-27 18:18:59 +0200
committerNicolai Haehnle <nhaehnle@gmail.com>2008-07-27 18:18:59 +0200
commit322677b8789c031024fb3fb4618f27e7a6ffec5d (patch)
tree0286bef79b8f41be94fb841a977f51cbecba7838
parent0973d348d7a9c8d50829a33112dceb4e7f7a61ef (diff)
r300: Implement hardware acceleration for ColorLogicOp
-rw-r--r--src/mesa/drivers/dri/r300/r300_cmdbuf.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h1
-rw-r--r--src/mesa/drivers/dri/r300/r300_reg.h4
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c44
5 files changed, 49 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index 4dc31614492..c069660eeaf 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -477,6 +477,8 @@ void r300InitCmdBuf(r300ContextPtr r300)
ALLOC_STATE(blend_color, always, 2, 0);
r300->hw.blend_color.cmd[0] = cmdpacket0(R300_RB3D_BLEND_COLOR, 1);
}
+ ALLOC_STATE(rop, always, 2, 0);
+ r300->hw.rop.cmd[0] = cmdpacket0(R300_RB3D_ROPCNTL, 1);
ALLOC_STATE(cb, always, R300_CB_CMDSIZE, 0);
r300->hw.cb.cmd[R300_CB_CMD_0] = cmdpacket0(R300_RB3D_COLOROFFSET0, 1);
r300->hw.cb.cmd[R300_CB_CMD_1] = cmdpacket0(R300_RB3D_COLORPITCH0, 1);
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 98af6d8f10a..d2017f8afeb 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -516,6 +516,7 @@ struct r300_hw_state {
struct r300_state_atom bld; /* blending (4E04) */
struct r300_state_atom cmk; /* colormask (4E0C) */
struct r300_state_atom blend_color; /* constant blend color */
+ struct r300_state_atom rop; /* ropcntl */
struct r300_state_atom cb; /* colorbuffer (4E28) */
struct r300_state_atom rb3d_dither_ctl; /* (4E50) */
struct r300_state_atom rb3d_aaresolve_ctl; /* (4E88) */
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index ec2b58377c5..562cd6afdb2 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -2249,7 +2249,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* 3D ROP Control. Stalls the 2d/3d datapath until it is idle. */
#define R300_RB3D_ROPCNTL 0x4e18
-/* TODO: fill in content here */
+# define R300_RB3D_ROPCNTL_ROP_ENABLE 0x00000004
+# define R300_RB3D_ROPCNTL_ROP_MASK (15 << 8)
+# define R300_RB3D_ROPCNTL_ROP_SHIFT 8
/* Color Compare Flip. Stalls the 2d/3d datapath until it is idle. */
#define R300_RB3D_CLRCMP_FLIPE 0x4e1c
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 58bc0884431..0a199e6faad 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -377,8 +377,6 @@ static int r300Fallback(GLcontext * ctx)
|| ctx->Stencil.WriteMask[0] !=
ctx->Stencil.WriteMask[1]));
- FALLBACK_IF(ctx->Color.ColorLogicOpEnabled);
-
if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
FALLBACK_IF(ctx->Point.PointSprite);
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 6931de4421d..ec17974d78c 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -321,6 +321,44 @@ static void r300BlendFuncSeparate(GLcontext * ctx,
r300SetBlendState(ctx);
}
+/**
+ * Translate LogicOp enums into hardware representation.
+ * Both use a very logical bit-wise layout, but unfortunately the order
+ * of bits is reversed.
+ */
+static GLuint translate_logicop(GLenum logicop)
+{
+ GLuint bits = logicop - GL_CLEAR;
+ bits = ((bits & 1) << 3) | ((bits & 2) << 1) | ((bits & 4) >> 1) | ((bits & 8) >> 3);
+ return bits << R300_RB3D_ROPCNTL_ROP_SHIFT;
+}
+
+/**
+ * Used internally to update the r300->hw hardware state to match the
+ * current OpenGL state.
+ */
+static void r300SetLogicOpState(GLcontext *ctx)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ R300_STATECHANGE(r300, rop);
+ if (RGBA_LOGICOP_ENABLED(ctx)) {
+ r300->hw.rop.cmd[1] = R300_RB3D_ROPCNTL_ROP_ENABLE |
+ translate_logicop(ctx->Color.LogicOp);
+ } else {
+ r300->hw.rop.cmd[1] = 0;
+ }
+}
+
+/**
+ * Called by Mesa when an application program changes the LogicOp state
+ * via glLogicOp.
+ */
+static void r300LogicOpcode(GLcontext *ctx, GLenum logicop)
+{
+ if (RGBA_LOGICOP_ENABLED(ctx))
+ r300SetLogicOpState(ctx);
+}
+
static void r300ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq )
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
@@ -2117,8 +2155,10 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state)
case GL_ALPHA_TEST:
r300SetAlphaState(ctx);
break;
- case GL_BLEND:
case GL_COLOR_LOGIC_OP:
+ r300SetLogicOpState(ctx);
+ /* fall-through, because logic op overrides blending */
+ case GL_BLEND:
r300SetBlendState(ctx);
break;
case GL_CLIP_PLANE0:
@@ -2188,6 +2228,7 @@ static void r300ResetHwState(r300ContextPtr r300)
r300UpdateTextureState(ctx);
r300SetBlendState(ctx);
+ r300SetLogicOpState(ctx);
r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef);
r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled);
@@ -2755,6 +2796,7 @@ void r300InitStateFuncs(struct dd_function_table *functions)
functions->Fogfv = r300Fogfv;
functions->FrontFace = r300FrontFace;
functions->ShadeModel = r300ShadeModel;
+ functions->LogicOpcode = r300LogicOpcode;
/* ARB_point_parameters */
functions->PointParameterfv = r300PointParameter;