Merge remote branch 'origin/mesa_7_7_branch'
[mesa.git] / src / mesa / drivers / dri / r300 / r300_state.c
index 1ac14267d5e67abf47cd759c548ebb320cf38169..1fd32d497b4a5d2a89743cdb729647b001e47e3b 100644 (file)
@@ -45,7 +45,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/framebuffer.h"
 #include "main/simple_list.h"
 #include "main/api_arrayelt.h"
-#include "main/texformat.h"
 
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
@@ -371,6 +370,7 @@ static void r300ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq )
        p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
        ip = (GLint *)ctx->Transform._ClipUserPlane[p];
 
+       R300_STATECHANGE( rmesa, vap_flush );
        R300_STATECHANGE( rmesa, vpucp[p] );
        rmesa->hw.vpucp[p].cmd[R300_VPUCP_X] = ip[0];
        rmesa->hw.vpucp[p].cmd[R300_VPUCP_Y] = ip[1];
@@ -471,6 +471,8 @@ static void r300SetEarlyZState(GLcontext * ctx)
                topZ = R300_ZTOP_DISABLE;
        else if (ctx->FragmentProgram._Current && ctx->FragmentProgram._Current->UsesKill)
                topZ = R300_ZTOP_DISABLE;
+       else if (r300->radeon.query.current)
+               topZ = R300_ZTOP_DISABLE;
 
        if (topZ != r300->hw.zstencil_format.cmd[2]) {
                /* Note: This completely reemits the stencil format.
@@ -587,7 +589,9 @@ static void r300SetDepthState(GLcontext * ctx)
        r300ContextPtr r300 = R300_CONTEXT(ctx);
 
        R300_STATECHANGE(r300, zs);
-       r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_STENCIL_ENABLE|R300_STENCIL_FRONT_BACK;
+       r300->hw.zs.cmd[R300_ZS_CNTL_0] &= (R300_STENCIL_ENABLE |
+                                           R300_STENCIL_FRONT_BACK |
+                                           R500_STENCIL_REFMASK_FRONT_BACK);
        r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_Z_FUNC_SHIFT);
 
        if (ctx->Depth.Test) {
@@ -601,11 +605,16 @@ static void r300SetDepthState(GLcontext * ctx)
 
 static void r300CatchStencilFallback(GLcontext *ctx)
 {
+       r300ContextPtr rmesa = R300_CONTEXT(ctx);
        const unsigned back = ctx->Stencil._BackFace;
 
-       if (ctx->Stencil._Enabled && (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back]
-               || ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[back]
-               || ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[back])) {
+       if (rmesa->radeon.radeonScreen->kernel_mm &&
+           (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)) {
+               r300SwitchFallback(ctx, R300_FALLBACK_STENCIL_TWOSIDE, GL_FALSE);
+       } else if (ctx->Stencil._Enabled &&
+                  (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back]
+                   || ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[back]
+                   || ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[back])) {
                r300SwitchFallback(ctx, R300_FALLBACK_STENCIL_TWOSIDE, GL_TRUE);
        } else {
                r300SwitchFallback(ctx, R300_FALLBACK_STENCIL_TWOSIDE, GL_FALSE);
@@ -912,11 +921,24 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
        rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
            (flag << R300_S_BACK_FUNC_SHIFT);
        rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;
+
+       if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+               rmesa->hw.zs.cmd[R300_ZS_CNTL_0] |= R500_STENCIL_REFMASK_FRONT_BACK;
+               R300_STATECHANGE(rmesa, zsb);
+               refmask = ((ctx->Stencil.Ref[back] & 0xff) << R300_STENCILREF_SHIFT)
+                       | ((ctx->Stencil.ValueMask[back] & 0xff) << R300_STENCILMASK_SHIFT);
+
+               rmesa->hw.zsb.cmd[R300_ZSB_CNTL_0] &=
+                       ~((R300_STENCILREF_MASK << R300_STENCILREF_SHIFT) |
+                         (R300_STENCILREF_MASK << R300_STENCILMASK_SHIFT));
+               rmesa->hw.zsb.cmd[R300_ZSB_CNTL_0] |= refmask;
+       }
 }
 
 static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
 {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
+       const unsigned back = ctx->Stencil._BackFace;
 
        r300CatchStencilFallback(ctx);
 
@@ -928,6 +950,13 @@ static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
            (ctx->Stencil.
             WriteMask[0] & R300_STENCILREF_MASK) <<
             R300_STENCILWRITEMASK_SHIFT;
+       if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+               R300_STATECHANGE(rmesa, zsb);
+               rmesa->hw.zsb.cmd[R300_ZSB_CNTL_0] |=
+                       (ctx->Stencil.
+                        WriteMask[back] & R300_STENCILREF_MASK) <<
+                       R300_STENCILWRITEMASK_SHIFT;
+       }
 }
 
 static void r300StencilOpSeparate(GLcontext * ctx, GLenum face,
@@ -1253,6 +1282,7 @@ static GLuint translate_lod_bias(GLfloat bias)
        return (((GLuint)b) << R300_LOD_BIAS_SHIFT) & R300_LOD_BIAS_MASK;
 }
 
+
 static void r300SetupTextures(GLcontext * ctx)
 {
        int i, mtu;
@@ -1275,7 +1305,7 @@ static void r300SetupTextures(GLcontext * ctx)
        r300->hw.txe.cmd[R300_TXE_ENABLE] = 0x0;
 
        mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
-       if (RADEON_DEBUG & DEBUG_STATE)
+       if (RADEON_DEBUG & RADEON_STATE)
                fprintf(stderr, "mtu=%d\n", mtu);
 
        if (mtu > R300_MAX_TEXTURE_UNITS) {
@@ -1300,7 +1330,7 @@ static void r300SetupTextures(GLcontext * ctx)
                                     t->pp_txformat & 0xff);
                        }
 
-                       if (RADEON_DEBUG & DEBUG_STATE)
+                       if (RADEON_DEBUG & RADEON_STATE)
                                fprintf(stderr,
                                        "Activating texture unit %d\n", i);
 
@@ -1345,6 +1375,28 @@ static void r300SetupTextures(GLcontext * ctx)
                }
        }
 
+       /* R3xx and R4xx chips require that the texture unit corresponding to
+        * KIL instructions is really enabled.
+        *
+        * We do some fakery here and in the state atom emit logic to enable
+        * the texture without tripping up the CS checker in the kernel.
+        */
+       if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
+               if (ctx->FragmentProgram._Current->UsesKill && last_hw_tmu < 0) {
+                       last_hw_tmu++;
+
+                       r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1;
+
+                       r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0] = 0;
+                       r300->hw.tex.chroma_key.cmd[R300_TEX_VALUE_0] = 0;
+                       r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0;
+                       r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0] = 0;
+                       r300->hw.tex.size.cmd[R300_TEX_VALUE_0] = 0; /* 1x1 texture */
+                       r300->hw.tex.format.cmd[R300_TEX_VALUE_0] = 0; /* A8 format */
+                       r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0] = 0;
+               }
+       }
+
        r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =
            cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, last_hw_tmu + 1);
        r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] =
@@ -1362,19 +1414,9 @@ static void r300SetupTextures(GLcontext * ctx)
        r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] =
            cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1);
 
-       if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
-               if (ctx->FragmentProgram._Current->UsesKill && last_hw_tmu < 0) {
-                       // The KILL operation requires the first texture unit
-                       // to be enabled.
-                       r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1;
-                       r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0;
-                       r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =
-                               cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 1);
-               }
-       }
        r300->vtbl.SetupFragmentShaderTextures(ctx, tmu_mappings);
 
-       if (RADEON_DEBUG & DEBUG_STATE)
+       if (RADEON_DEBUG & RADEON_STATE)
                fprintf(stderr, "TX_ENABLE: %08x  last_hw_tmu=%d\n",
                        r300->hw.txe.cmd[R300_TXE_ENABLE], last_hw_tmu);
 }
@@ -1644,7 +1686,7 @@ void r300VapCntl(r300ContextPtr rmesa, GLuint input_count,
 static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state)
 {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
-       if (RADEON_DEBUG & DEBUG_STATE)
+       if (RADEON_DEBUG & RADEON_STATE)
                fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
                        _mesa_lookup_enum_by_nr(cap),
                        state ? "GL_TRUE" : "GL_FALSE");
@@ -1699,7 +1741,8 @@ static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state)
                r300SetPolygonOffsetState(ctx, state);
                break;
        case GL_SCISSOR_TEST:
-               radeon_firevertices(&rmesa->radeon);
+               if (!rmesa->radeon.radeonScreen->kernel_mm)
+                       radeon_firevertices(&rmesa->radeon);
                rmesa->radeon.state.scissor.enabled = state;
                radeonUpdateScissor( ctx );
                break;
@@ -1721,7 +1764,7 @@ static void r300ResetHwState(r300ContextPtr r300)
 
        has_tcl = r300->options.hw_tcl_enabled;
 
-       if (RADEON_DEBUG & DEBUG_STATE)
+       if (RADEON_DEBUG & RADEON_STATE)
                fprintf(stderr, "%s\n", __FUNCTION__);
 
        radeon_firevertices(&r300->radeon);
@@ -2103,13 +2146,13 @@ static void r500SetupPixelShader(GLcontext *ctx)
        rmesa->hw.fp.cmd[R500_FP_PIXSIZE] = code->max_temp_idx;
 
        rmesa->hw.fp.cmd[R500_FP_CODE_ADDR] =
-           R500_US_CODE_START_ADDR(code->inst_offset) |
+           R500_US_CODE_START_ADDR(0) |
            R500_US_CODE_END_ADDR(code->inst_end);
        rmesa->hw.fp.cmd[R500_FP_CODE_RANGE] =
-           R500_US_CODE_RANGE_ADDR(code->inst_offset) |
+           R500_US_CODE_RANGE_ADDR(0) |
            R500_US_CODE_RANGE_SIZE(code->inst_end);
        rmesa->hw.fp.cmd[R500_FP_CODE_OFFSET] =
-           R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
+           R500_US_CODE_OFFSET_ADDR(0);
 
        R300_STATECHANGE(rmesa, r500fp);
        /* Emit our shader... */
@@ -2234,6 +2277,15 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
                _mesa_update_draw_buffer_bounds(ctx);
 
                R300_STATECHANGE(r300, cb);
+               R300_STATECHANGE(r300, zb);
+       }
+
+       if (new_state & (_NEW_LIGHT)) {
+               R300_STATECHANGE(r300, shade2);
+               if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION)
+                       r300->hw.shade2.cmd[1] |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
+               else
+                       r300->hw.shade2.cmd[1] &= ~R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
        }
 
        r300->radeon.NewGLState |= new_state;