Merge branch 'master-merge' into vbo-0.2
[mesa.git] / src / mesa / drivers / dri / r200 / r200_tcl.c
index f6461a164e6a3f12c391ee1e509bf73b2b390d9f..0b3bb281e016604f44259f7336a9dc68b4e48370 100644 (file)
@@ -40,7 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "colormac.h"
 #include "light.h"
 
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
 #include "tnl/tnl.h"
 #include "tnl/t_pipeline.h"
 
@@ -68,7 +68,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define HAVE_ELTS        1
 
 
-#define HW_POINTS           ((ctx->_TriangleCaps & DD_POINT_SIZE) ? \
+#define HW_POINTS           ((ctx->Point.PointSprite || \
+                               ((ctx->_TriangleCaps & (DD_POINT_SIZE | DD_POINT_ATTEN)) && \
+                               !(ctx->_TriangleCaps & (DD_POINT_SMOOTH)))) ? \
                                R200_VF_PRIM_POINT_SPRITES : R200_VF_PRIM_POINTS)
 #define HW_LINES            R200_VF_PRIM_LINES
 #define HW_LINE_LOOP        0
@@ -268,6 +270,17 @@ void r200TclPrimitive( GLcontext *ctx,
 
    if (newprim != rmesa->tcl.hw_primitive ||
        !discrete_prim[hw_prim&0xf]) {
+      /* need to disable perspective-correct texturing for point sprites */
+      if ((prim & PRIM_MODE_MASK) == GL_POINTS && ctx->Point.PointSprite) {
+        if (rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE) {
+           R200_STATECHANGE( rmesa, set );
+           rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PERSPECTIVE_ENABLE;
+        }
+      }
+      else if (!(rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE)) {
+        R200_STATECHANGE( rmesa, set );
+        rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PERSPECTIVE_ENABLE;
+      }
       R200_NEWPRIM( rmesa );
       rmesa->tcl.hw_primitive = newprim;
    }
@@ -390,26 +403,67 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
    if (rmesa->NewGLState)
       r200ValidateState( ctx );
 
+   if (!ctx->VertexProgram._Enabled) {
    /* NOTE: inputs != tnl->render_inputs - these are the untransformed
     * inputs.
     */
-   if (ctx->Light.Enabled) {
-      inputs |= VERT_BIT_NORMAL;
+      if (ctx->Light.Enabled) {
+        inputs |= VERT_BIT_NORMAL;
+      }
+
       if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
         inputs |= VERT_BIT_COLOR1;
       }
-   }
 
-   if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) {
-      inputs |= VERT_BIT_FOG;
-   }
+      if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) {
+        inputs |= VERT_BIT_FOG;
+      }
 
-   for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) {
-      if (ctx->Texture.Unit[i]._ReallyEnabled) {
-        if (rmesa->TexGenNeedNormals[i]) {
-           inputs |= VERT_BIT_NORMAL;
+      for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) {
+        if (ctx->Texture.Unit[i]._ReallyEnabled) {
+           if (rmesa->TexGenNeedNormals[i]) {
+              inputs |= VERT_BIT_NORMAL;
+           }
+           inputs |= VERT_BIT_TEX(i);
         }
-        inputs |= VERT_BIT_TEX(i);
+      }
+   }
+   else {
+      /* vtx_tcl_output_vtxfmt_0/1 need to match configuration of "fragment
+        part", since using some vertex interpolator later which is not in
+        out_vtxfmt0/1 will lock up. It seems to be ok to write in vertex
+        prog to a not enabled output however, so just don't mess with it.
+        We only need to change compsel. */
+      GLuint out_compsel = 0;
+      GLuint vp_out = rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten;
+      /* can't handle other inputs, generic attribs etc. currently - should never arrive here */
+      assert ((rmesa->curr_vp_hw->mesa_program.Base.InputsRead &
+        ~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 |
+         VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 |
+         VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) == 0);
+      inputs |= rmesa->curr_vp_hw->mesa_program.Base.InputsRead;
+      assert(vp_out & (1 << VERT_RESULT_HPOS));
+      out_compsel = R200_OUTPUT_XYZW;
+      if (vp_out & (1 << VERT_RESULT_COL0)) {
+        out_compsel |= R200_OUTPUT_COLOR_0;
+      }
+      if (vp_out & (1 << VERT_RESULT_COL1)) {
+        out_compsel |= R200_OUTPUT_COLOR_1;
+      }
+      if (vp_out & (1 << VERT_RESULT_FOGC)) {
+         out_compsel |= R200_OUTPUT_DISCRETE_FOG;
+      }
+      if (vp_out & (1 << VERT_RESULT_PSIZ)) {
+        out_compsel |= R200_OUTPUT_PT_SIZE;
+      }
+      for (i = VERT_RESULT_TEX0; i < VERT_RESULT_TEX6; i++) {
+        if (vp_out & (1 << i)) {
+           out_compsel |= R200_OUTPUT_TEX_0 << (i - VERT_RESULT_TEX0);
+        }
+      }
+      if (rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] != out_compsel) {
+        R200_STATECHANGE( rmesa, vtx );
+        rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = out_compsel;
       }
    }
 
@@ -485,7 +539,7 @@ static void transition_to_swtnl( GLcontext *ctx )
     * need to put the card into D3D mode to make it work:
     */
    R200_STATECHANGE( rmesa, vap );
-   rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_TCL_ENABLE;
+   rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~(R200_VAP_TCL_ENABLE|R200_VAP_PROG_VTX_SHADER_ENABLE);
 }
 
 static void transition_to_hwtnl( GLcontext *ctx )
@@ -512,6 +566,10 @@ static void transition_to_hwtnl( GLcontext *ctx )
    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_TCL_ENABLE;
    rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_FORCE_W_TO_ONE;
 
+   if (ctx->VertexProgram._Enabled) {
+      rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE;
+   }
+
    if ( ((rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK)
       == R200_FOG_USE_SPEC_ALPHA) &&
       (ctx->Fog.FogCoordinateSource == GL_FOG_COORD )) {