radeon: Invert front face winding when rendering to FBO.
[mesa.git] / src / mesa / drivers / dri / r300 / r300_state.c
index 67bd6ec33bef06e9d6bf10c7416978ca21ec9afe..12fbf281d991bc4c41b9d0905826ef7d25e1b1e3 100644 (file)
@@ -434,6 +434,10 @@ static void r300UpdateCulling(GLcontext * ctx)
                break;
        }
 
+       /* Winding is inverted when rendering to FBO */
+       if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
+               val ^= R300_FRONT_FACE_CW;
+
        R300_STATECHANGE(r300, cul);
        r300->hw.cul.cmd[R300_CUL_CULL] = val;
 }
@@ -452,9 +456,9 @@ static void r300SetPolygonOffsetState(GLcontext * ctx, GLboolean state)
 
 static GLboolean current_fragment_program_writes_depth(GLcontext* ctx)
 {
-       struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
 
-       return (fp && fp->writes_depth);
+       return ctx->FragmentProgram._Current && r300->selected_fp->writes_depth;
 }
 
 static void r300SetEarlyZState(GLcontext * ctx)
@@ -1095,18 +1099,17 @@ r300FetchStateParameter(GLcontext * ctx,
  */
 static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
 {
-       struct r300_fragment_program *fp;
+       r300ContextPtr rmesa = R300_CONTEXT(ctx);
        struct gl_program_parameter_list *paramList;
        GLuint i;
 
        if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)))
                return;
 
-       fp = (struct r300_fragment_program *)ctx->FragmentProgram._Current;
-       if (!fp)
+       if (!ctx->FragmentProgram._Current || !rmesa->selected_fp)
                return;
 
-       paramList = fp->Base.Base.Parameters;
+       paramList = rmesa->selected_fp->Base->Parameters;
 
        if (!paramList)
                return;
@@ -1227,8 +1230,7 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
        int i;
-       struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
-       struct r300_fragment_program_code *code = &fp->code.r300;
+       struct r300_fragment_program_code *code = &r300->selected_fp->code.r300;
 
        R300_STATECHANGE(r300, fpt);
 
@@ -1268,9 +1270,9 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
 
 static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
 {
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
        int i;
-       struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
-       struct r500_fragment_program_code *code = &fp->code.r500;
+       struct r500_fragment_program_code *code = &r300->selected_fp->code.r500;
 
        /* find all the texture instructions and relocate the texture units */
        for (i = 0; i < code->inst_end + 1; i++) {
@@ -1318,8 +1320,6 @@ static void r300SetupTextures(GLcontext * ctx)
        int hw_tmu = 0;
        int last_hw_tmu = -1;   /* -1 translates into no setup costs for fields */
        int tmu_mappings[R300_MAX_TEXTURE_UNITS] = { -1, };
-       struct r300_fragment_program *fp = (struct r300_fragment_program *)
-           (char *)ctx->FragmentProgram._Current;
 
        R300_STATECHANGE(r300, txe);
        R300_STATECHANGE(r300, tex.filter);
@@ -1422,7 +1422,7 @@ static void r300SetupTextures(GLcontext * ctx)
            cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1);
 
        if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
-               if (fp->Base.UsesKill && last_hw_tmu < 0) {
+               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;
@@ -1460,11 +1460,11 @@ static void r300SetupRSUnit(GLcontext * ctx)
        hw_tcl_on = r300->options.hw_tcl_enabled;
 
        if (hw_tcl_on)
-               OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten;
+               OutputsWritten.vp_outputs = r300->selected_vp->Base->Base.OutputsWritten;
        else
                RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset);
 
-       InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
+       InputsRead = r300->selected_fp->Base->InputsRead;
 
        R300_STATECHANGE(r300, ri);
        R300_STATECHANGE(r300, rc);
@@ -1523,29 +1523,6 @@ static void r300SetupRSUnit(GLcontext * ctx)
                ++fp_reg;
        }
 
-       if (InputsRead & FRAG_BIT_WPOS) {
-               r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | R300_RS_TEX_PTR(rs_tex_count);
-               r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg);
-               InputsRead &= ~FRAG_BIT_WPOS;
-               rs_tex_count += 4;
-               ++tex_ip;
-               ++fp_reg;
-       }
-
-       if (InputsRead & FRAG_BIT_FOGC) {
-               if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) {
-                       r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_S(0) | R300_RS_SEL_T(R300_RS_SEL_K0) | R300_RS_SEL_R(R300_RS_SEL_K0);
-                       r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= R300_RS_SEL_Q(R300_RS_SEL_K1) | R300_RS_TEX_PTR(rs_tex_count);
-                       r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R300_RS_INST_TEX_ID(tex_ip) | R300_RS_INST_TEX_CN_WRITE | R300_RS_INST_TEX_ADDR(fp_reg);
-                       InputsRead &= ~FRAG_BIT_FOGC;
-                       rs_tex_count += 4;
-                       ++tex_ip;
-                       ++fp_reg;
-               } else {
-                       WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n");
-               }
-       }
-
        /* Setup default color if no color or tex was set */
        if (rs_tex_count == 0 && col_ip == 0) {
                r300->hw.rr.cmd[R300_RR_INST_0] = R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_ADDR(0);
@@ -1577,11 +1554,11 @@ static void r500SetupRSUnit(GLcontext * ctx)
        hw_tcl_on = r300->options.hw_tcl_enabled;
 
        if (hw_tcl_on)
-               OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten;
+               OutputsWritten.vp_outputs = r300->selected_vp->Base->Base.OutputsWritten;
        else
                RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset);
 
-       InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
+       InputsRead = r300->selected_fp->Base->InputsRead;
 
        R300_STATECHANGE(r300, ri);
        R300_STATECHANGE(r300, rc);
@@ -1644,36 +1621,6 @@ static void r500SetupRSUnit(GLcontext * ctx)
                ++fp_reg;
        }
 
-       if (InputsRead & FRAG_BIT_WPOS) {
-               r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= ((rs_tex_count + 0) << R500_RS_IP_TEX_PTR_S_SHIFT) |
-                       ((rs_tex_count + 1) << R500_RS_IP_TEX_PTR_T_SHIFT) |
-                       ((rs_tex_count + 2) << R500_RS_IP_TEX_PTR_R_SHIFT) |
-                       ((rs_tex_count + 3) << R500_RS_IP_TEX_PTR_Q_SHIFT);
-
-               r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg);
-               InputsRead &= ~FRAG_BIT_WPOS;
-               rs_tex_count += 4;
-               ++tex_ip;
-               ++fp_reg;
-       }
-
-       if (InputsRead & FRAG_BIT_FOGC) {
-               if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) {
-                       r300->hw.ri.cmd[R300_RI_INTERP_0 + tex_ip] |= (rs_tex_count << R500_RS_IP_TEX_PTR_S_SHIFT) |
-                               (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) |
-                               (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
-                               (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT);
-
-                       r300->hw.rr.cmd[R300_RR_INST_0 + tex_ip] |= R500_RS_INST_TEX_ID(tex_ip) | R500_RS_INST_TEX_CN_WRITE | R500_RS_INST_TEX_ADDR(fp_reg);
-                       InputsRead &= ~FRAG_BIT_FOGC;
-                       rs_tex_count += 4;
-                       ++tex_ip;
-                       ++fp_reg;
-               } else {
-                       WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n");
-               }
-       }
-
        /* Setup default color if no color or tex was set */
        if (rs_tex_count == 0 && col_ip == 0) {
                r300->hw.rr.cmd[R300_RR_INST_0] = R500_RS_INST_COL_ID(0) | R500_RS_INST_COL_ADDR(0);
@@ -2038,43 +1985,51 @@ static void r300ResetHwState(r300ContextPtr r300)
 
 void r300UpdateShaders(r300ContextPtr rmesa)
 {
-       GLcontext *ctx;
-       struct r300_fragment_program *fp;
-       int i;
-
-       ctx = rmesa->radeon.glCtx;
-       fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
+       GLcontext *ctx = rmesa->radeon.glCtx;
 
        /* should only happenen once, just after context is created */
        /* TODO: shouldn't we fallback to sw here? */
-       if (!fp) {
+       if (!ctx->FragmentProgram._Current) {
                _mesa_fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
                return;
        }
 
-       if (rmesa->radeon.NewGLState && rmesa->options.hw_tcl_enabled) {
-               for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
-                       rmesa->temp_attrib[i] =
-                           TNL_CONTEXT(ctx)->vb.AttribPtr[i];
-                       TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
-                           &rmesa->dummy_attrib[i];
-               }
-
-               _tnl_UpdateFixedFunctionProgram(ctx);
+       {
+               struct r300_fragment_program *fp;
 
-               for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
-                       TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
-                           rmesa->temp_attrib[i];
-               }
+               fp = r300SelectFragmentShader(ctx);
+               if (!fp->translated)
+                       r300TranslateFragmentShader(ctx, fp);
 
-               r300SelectVertexShader(rmesa);
-               r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, rmesa->selected_vp->error);
+               r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error);
        }
 
-       if (!fp->translated || rmesa->radeon.NewGLState)
-               r300TranslateFragmentShader(ctx, ctx->FragmentProgram._Current);
+       if (rmesa->options.hw_tcl_enabled) {
+               struct r300_vertex_program *vp;
+
+               if (rmesa->radeon.NewGLState) {
+                       int i;
+                       for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
+                               rmesa->temp_attrib[i] =
+                                   TNL_CONTEXT(ctx)->vb.AttribPtr[i];
+                               TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
+                                   &rmesa->dummy_attrib[i];
+                       }
+
+                       _tnl_UpdateFixedFunctionProgram(ctx);
 
-       r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error);
+                       for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
+                               TNL_CONTEXT(ctx)->vb.AttribPtr[i] =
+                                   rmesa->temp_attrib[i];
+                       }
+               }
+
+               vp = r300SelectVertexShader(ctx);
+               if (!vp->translated)
+                       r300TranslateVertexShader(vp);
+
+               r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, vp->error);
+       }
 
        r300UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
        rmesa->radeon.NewGLState = 0;
@@ -2104,7 +2059,7 @@ static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx,
 static void r300SetupPixelShader(GLcontext *ctx)
 {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
-       struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
+       struct r300_fragment_program *fp = rmesa->selected_fp;
        struct r300_fragment_program_code *code;
        int i, k;
 
@@ -2150,8 +2105,7 @@ static void r300SetupPixelShader(GLcontext *ctx)
        R300_STATECHANGE(rmesa, fpp);
        rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_PFS_PARAM_0_X, code->const_nr * 4);
        for (i = 0; i < code->const_nr; i++) {
-               const GLfloat *constant = get_fragmentprogram_constant(ctx,
-                       &fp->Base.Base, code->constant[i]);
+               const GLfloat *constant = get_fragmentprogram_constant(ctx, fp->Base, code->constant[i]);
                rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat24(constant[0]);
                rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat24(constant[1]);
                rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(constant[2]);
@@ -2176,7 +2130,7 @@ static void r300SetupPixelShader(GLcontext *ctx)
 static void r500SetupPixelShader(GLcontext *ctx)
 {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
-       struct r300_fragment_program *fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
+       struct r300_fragment_program *fp = rmesa->selected_fp;
        int i;
        struct r500_fragment_program_code *code;
 
@@ -2212,8 +2166,7 @@ static void r500SetupPixelShader(GLcontext *ctx)
 
        R300_STATECHANGE(rmesa, r500fp_const);
        for (i = 0; i < code->const_nr; i++) {
-               const GLfloat *constant = get_fragmentprogram_constant(ctx,
-                       &fp->Base.Base, code->constant[i]);
+               const GLfloat *constant = get_fragmentprogram_constant(ctx, fp->Base, code->constant[i]);
                rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat32(constant[0]);
                rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat32(constant[1]);
                rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat32(constant[2]);
@@ -2276,20 +2229,17 @@ void r300SetupVAP(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten)
 
        rmesa->hw.vic.cmd[R300_VIC_CNTL_0] = r300VAPInputCntl0(ctx, InputsRead);
        rmesa->hw.vic.cmd[R300_VIC_CNTL_1] = r300VAPInputCntl1(ctx, InputsRead);
-       rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead);
-       rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten, ctx->FragmentProgram._Current->Base.InputsRead);
+       rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten);
+       rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten);
 }
 
 void r300UpdateShaderStates(r300ContextPtr rmesa)
 {
        GLcontext *ctx;
        ctx = rmesa->radeon.glCtx;
-       struct r300_fragment_program *r300_fp;
-
-       r300_fp = (struct r300_fragment_program *) ctx->FragmentProgram._Current;
 
        /* should only happenen once, just after context is created */
-       if (!r300_fp)
+       if (!ctx->FragmentProgram._Current)
                return;
 
        r300SetEarlyZState(ctx);