r300: Implement hardware acceleration for ColorLogicOp
authorNicolai Haehnle <nhaehnle@gmail.com>
Sun, 27 Jul 2008 16:18:59 +0000 (18:18 +0200)
committerNicolai Haehnle <nhaehnle@gmail.com>
Sun, 27 Jul 2008 16:18:59 +0000 (18:18 +0200)
src/mesa/drivers/dri/r300/r300_cmdbuf.c
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_reg.h
src/mesa/drivers/dri/r300/r300_render.c
src/mesa/drivers/dri/r300/r300_state.c

index 4dc31614492c28b5485c624691e98662c7344735..c069660eeafb257c83f7f909f8025fca83618535 100644 (file)
@@ -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);
index 98af6d8f10a6c61cbc9686cb555c1c43cd0b4853..d2017f8afeb9d0a6259cb87648a6e145ae556202 100644 (file)
@@ -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) */
index ec2b58377c57a1cffc99932945f841cd82b8816c..562cd6afdb27aea3be86ef0bf78a2de41a3af0db 100644 (file)
@@ -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
index 58bc0884431418b3cac316d72fc4fe5ef55d3679..0a199e6faad1f5cc739521b16bf7a0f456c85a31 100644 (file)
@@ -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);
 
index 6931de4421d3c0edf221f355dacba87949aa4c8e..ec17974d78c5a79e7df1d3d273427066d0cffeb4 100644 (file)
@@ -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;