Merge commit 'origin/master' into gallium-map-range
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_maos_arrays.c
index cec05a89d7ed58316da2235f36c6ca99d288bd24..31eea13f4eff6fdd1a95be574eda79a58eef778d 100644 (file)
@@ -1,4 +1,3 @@
-/* $XFree86$ */
 /**************************************************************************
 
 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
@@ -33,24 +32,23 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *   Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "glheader.h"
-#include "imports.h"
-#include "mtypes.h"
-#include "mmath.h"
-#include "macros.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
 
 #include "swrast_setup/swrast_setup.h"
 #include "math/m_translate.h"
 #include "tnl/tnl.h"
-#include "tnl/t_context.h"
-#include "tnl/t_imm_debug.h"
 
 #include "radeon_context.h"
 #include "radeon_ioctl.h"
 #include "radeon_state.h"
 #include "radeon_swtcl.h"
 #include "radeon_maos.h"
+#include "radeon_tcl.h"
 
+#if 0
 /* Usage:
  *   - from radeon_tcl_render
  *   - call radeonEmitArrays to ensure uptodate arrays in dma
@@ -70,7 +68,7 @@ static void emit_ubyte_rgba3( GLcontext *ctx,
 
    if (RADEON_DEBUG & DEBUG_VERTS)
       fprintf(stderr, "%s count %d stride %d out %p\n",
-             __FUNCTION__, count, stride, out);
+             __FUNCTION__, count, stride, (void *)out);
 
    for (i = 0; i < count; i++) {
       out->red   = *data;
@@ -82,29 +80,6 @@ static void emit_ubyte_rgba3( GLcontext *ctx,
    }
 }
 
-
-#if defined(USE_X86_ASM)
-#define COPY_DWORDS( dst, src, nr )                                    \
-do {                                                                   \
-       int __tmp;                                                      \
-       __asm__ __volatile__( "rep ; movsl"                             \
-                             : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
-                             : "0" (nr),                               \
-                               "D" ((long)dst),                        \
-                               "S" ((long)src) );                      \
-} while (0)
-#else
-#define COPY_DWORDS( dst, src, nr )            \
-do {                                           \
-   int j;                                      \
-   for ( j = 0 ; j < nr ; j++ )                        \
-      dst[j] = ((int *)src)[j];                        \
-   dst += nr;                                  \
-} while (0)
-#endif
-
-
-
 static void emit_ubyte_rgba4( GLcontext *ctx,
                              struct radeon_dma_region *rvb,
                              char *data,
@@ -171,8 +146,91 @@ static void emit_ubyte_rgba( GLcontext *ctx,
       break;
    }
 }
+#endif
+
+#if defined(USE_X86_ASM)
+#define COPY_DWORDS( dst, src, nr )                                    \
+do {                                                                   \
+       int __tmp;                                                      \
+       __asm__ __volatile__( "rep ; movsl"                             \
+                             : "=%c" (__tmp), "=D" (dst), "=S" (__tmp) \
+                             : "0" (nr),                               \
+                               "D" ((long)dst),                        \
+                               "S" ((long)src) );                      \
+} while (0)
+#else
+#define COPY_DWORDS( dst, src, nr )            \
+do {                                           \
+   int j;                                      \
+   for ( j = 0 ; j < nr ; j++ )                        \
+      dst[j] = ((int *)src)[j];                        \
+   dst += nr;                                  \
+} while (0)
+#endif
+
+static void emit_vecfog( GLcontext *ctx,
+                        struct radeon_dma_region *rvb,
+                        char *data,
+                        int stride,
+                        int count )
+{
+   int i;
+   GLfloat *out;
+
+   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+   if (RADEON_DEBUG & DEBUG_VERTS)
+      fprintf(stderr, "%s count %d stride %d\n",
+             __FUNCTION__, count, stride);
+
+   assert (!rvb->buf);
+
+   if (stride == 0) {
+      radeonAllocDmaRegion( rmesa, rvb, 4, 4 );
+      count = 1;
+      rvb->aos_start = GET_START(rvb);
+      rvb->aos_stride = 0;
+      rvb->aos_size = 1;
+   }
+   else {
+      radeonAllocDmaRegion( rmesa, rvb, count * 4, 4 );        /* alignment? */
+      rvb->aos_start = GET_START(rvb);
+      rvb->aos_stride = 1;
+      rvb->aos_size = 1;
+   }
+
+   /* Emit the data
+    */
+   out = (GLfloat *)(rvb->address + rvb->start);
+   for (i = 0; i < count; i++) {
+      out[0] = radeonComputeFogBlendFactor( ctx, *(GLfloat *)data );
+      out++;
+      data += stride;
+   }
+}
 
+static void emit_vec4( GLcontext *ctx,
+                      struct radeon_dma_region *rvb,
+                      char *data,
+                      int stride,
+                      int count )
+{
+   int i;
+   int *out = (int *)(rvb->address + rvb->start);
 
+   if (RADEON_DEBUG & DEBUG_VERTS)
+      fprintf(stderr, "%s count %d stride %d\n",
+             __FUNCTION__, count, stride);
+
+   if (stride == 4)
+      COPY_DWORDS( out, data, count );
+   else
+      for (i = 0; i < count; i++) {
+        out[0] = *(int *)data;
+        out++;
+        data += stride;
+      }
+}
 
 
 static void emit_vec8( GLcontext *ctx,
@@ -210,7 +268,7 @@ static void emit_vec12( GLcontext *ctx,
 
    if (RADEON_DEBUG & DEBUG_VERTS)
       fprintf(stderr, "%s count %d stride %d out %p data %p\n",
-             __FUNCTION__, count, stride, out, data);
+             __FUNCTION__, count, stride, (void *)out, (void *)data);
 
    if (stride == 12)
       COPY_DWORDS( out, data, count*3 );
@@ -283,6 +341,9 @@ static void emit_vector( GLcontext *ctx,
    /* Emit the data
     */
    switch (size) {
+   case 1:
+      emit_vec4( ctx, rvb, data, stride, count );
+      break;
    case 2:
       emit_vec8( ctx, rvb, data, stride, count );
       break;
@@ -365,6 +426,7 @@ static void emit_tex_vector( GLcontext *ctx,
 
    switch (size) {
    case 4: emitsize = 3; break;
+   case 3: emitsize = 3; break;
    default: emitsize = 2; break;
    }
 
@@ -394,7 +456,7 @@ static void emit_tex_vector( GLcontext *ctx,
       emit_vec8( ctx, rvb, data, stride, count );
       break;
    case 3:
-      emit_vec8( ctx, rvb, data, stride, count );
+      emit_vec12( ctx, rvb, data, stride, count );
       break;
    case 4:
       emit_stq_vec( ctx, rvb, data, stride, count );
@@ -409,7 +471,7 @@ static void emit_tex_vector( GLcontext *ctx,
 
 
 
-/* Emit any changed arrays to new agp memory, re-emit a packet to
+/* Emit any changed arrays to new GART memory, re-emit a packet to
  * update the arrays.  
  */
 void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
@@ -420,10 +482,12 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
    GLuint nr = 0;
    GLuint vfmt = 0;
    GLuint count = VB->Count;
-   GLuint vtx;
+   GLuint vtx, unit;
    
+#if 0
    if (RADEON_DEBUG & DEBUG_VERTS) 
       _tnl_print_vert_flags( __FUNCTION__, inputs );
+#endif
 
    if (1) {
       if (!rmesa->tcl.obj.buf) 
@@ -439,6 +503,7 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
       case 3: vfmt |= RADEON_CP_VC_FRMT_Z;
       case 2: vfmt |= RADEON_CP_VC_FRMT_XY;
       default:
+         break;
       }
       component[nr++] = &rmesa->tcl.obj;
    }
@@ -458,39 +523,27 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
    }
 
    if (inputs & VERT_BIT_COLOR0) {
-      if (VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE) {
-        if (!rmesa->tcl.rgba.buf)
-           emit_ubyte_rgba( ctx, 
-                            &rmesa->tcl.rgba, 
-                            (char *)VB->ColorPtr[0]->Ptr,
-                            VB->ColorPtr[0]->Size,
-                            VB->ColorPtr[0]->StrideB,
-                            count);
-
-        vfmt |= RADEON_CP_VC_FRMT_PKCOLOR; 
+      int emitsize;
+      if (VB->ColorPtr[0]->size == 4 &&
+         (VB->ColorPtr[0]->stride != 0 ||
+          VB->ColorPtr[0]->data[0][3] != 1.0)) {
+        vfmt |= RADEON_CP_VC_FRMT_FPCOLOR | RADEON_CP_VC_FRMT_FPALPHA;
+        emitsize = 4;
       }
+
       else {
-        int emitsize;
+        vfmt |= RADEON_CP_VC_FRMT_FPCOLOR;
+        emitsize = 3;
+      }
 
-        if (VB->ColorPtr[0]->Size == 4 &&
-            (VB->ColorPtr[0]->StrideB != 0 ||
-             ((GLfloat *)VB->ColorPtr[0]->Ptr)[3] != 1.0)) { 
-           vfmt |= RADEON_CP_VC_FRMT_FPCOLOR | RADEON_CP_VC_FRMT_FPALPHA;
-           emitsize = 4;
-        }
-        else { 
-           vfmt |= RADEON_CP_VC_FRMT_FPCOLOR;
-           emitsize = 3;
-        }
+      if (!rmesa->tcl.rgba.buf)
+        emit_vector( ctx,
+                     &(rmesa->tcl.rgba),
+                     (char *)VB->ColorPtr[0]->data,
+                     emitsize,
+                     VB->ColorPtr[0]->stride,
+                     count);
 
-        if (!rmesa->tcl.rgba.buf)
-           emit_vector( ctx, 
-                        &(rmesa->tcl.rgba), 
-                        (char *)VB->ColorPtr[0]->Ptr,
-                        emitsize,
-                        VB->ColorPtr[0]->StrideB,
-                        count);
-      }
 
       component[nr++] = &rmesa->tcl.rgba;
    }
@@ -498,60 +551,66 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
 
    if (inputs & VERT_BIT_COLOR1) {
       if (!rmesa->tcl.spec.buf) {
-        if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE)
-           radeon_import_float_spec_colors( ctx );
-
-        emit_ubyte_rgba( ctx, 
-                         &rmesa->tcl.spec, 
-                         (char *)VB->SecondaryColorPtr[0]->Ptr,
-                         3,
-                         VB->SecondaryColorPtr[0]->StrideB,
-                         count);
+
+        emit_vector( ctx,
+                     &rmesa->tcl.spec,
+                     (char *)VB->SecondaryColorPtr[0]->data,
+                     3,
+                     VB->SecondaryColorPtr[0]->stride,
+                     count);
       }
 
-      vfmt |= RADEON_CP_VC_FRMT_PKSPEC; 
+      vfmt |= RADEON_CP_VC_FRMT_FPSPEC;
       component[nr++] = &rmesa->tcl.spec;
    }
 
-   vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
-         ~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1));
-      
-   if (inputs & VERT_BIT_TEX0) {
-      if (!rmesa->tcl.tex[0].buf)
-        emit_tex_vector( ctx, 
-                         &(rmesa->tcl.tex[0]), 
-                         (char *)VB->TexCoordPtr[0]->data,
-                         VB->TexCoordPtr[0]->size,
-                         VB->TexCoordPtr[0]->stride,
-                         count );
-
-      switch( VB->TexCoordPtr[0]->size ) {
-      case 4:
-        vtx |= RADEON_TCL_VTX_Q0; 
-        vfmt |= RADEON_CP_VC_FRMT_Q0;
-      default: 
-        vfmt |= RADEON_CP_VC_FRMT_ST0;
-      }
-      component[nr++] = &rmesa->tcl.tex[0];
+/* FIXME: not sure if this is correct. May need to stitch this together with
+   secondary color. It seems odd that for primary color color and alpha values
+   are emitted together but for secondary color not. */
+   if (inputs & VERT_BIT_FOG) {
+      if (!rmesa->tcl.fog.buf)
+        emit_vecfog( ctx,
+                     &(rmesa->tcl.fog),
+                     (char *)VB->FogCoordPtr->data,
+                     VB->FogCoordPtr->stride,
+                     count);
+
+      vfmt |= RADEON_CP_VC_FRMT_FPFOG;
+      component[nr++] = &rmesa->tcl.fog;
    }
 
-   if (inputs & VERT_BIT_TEX1) {
-      if (!rmesa->tcl.tex[1].buf)
-        emit_tex_vector( ctx, 
-                         &(rmesa->tcl.tex[1]), 
-                         (char *)VB->TexCoordPtr[1]->data,
-                         VB->TexCoordPtr[1]->size,
-                         VB->TexCoordPtr[1]->stride,
-                         count );
-        
-      switch( VB->TexCoordPtr[1]->size ) {
-      case 4: 
-        vtx |= RADEON_TCL_VTX_Q1;
-        vfmt |= RADEON_CP_VC_FRMT_Q1;
-      default: 
-        vfmt |= RADEON_CP_VC_FRMT_ST1;
+
+   vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
+         ~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1|RADEON_TCL_VTX_Q2));
+      
+   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+      if (inputs & VERT_BIT_TEX(unit)) {
+        if (!rmesa->tcl.tex[unit].buf)
+           emit_tex_vector( ctx,
+                            &(rmesa->tcl.tex[unit]),
+                            (char *)VB->TexCoordPtr[unit]->data,
+                            VB->TexCoordPtr[unit]->size,
+                            VB->TexCoordPtr[unit]->stride,
+                            count );
+
+        vfmt |= RADEON_ST_BIT(unit);
+         /* assume we need the 3rd coord if texgen is active for r/q OR at least
+           3 coords are submitted. This may not be 100% correct */
+         if (VB->TexCoordPtr[unit]->size >= 3) {
+           vtx |= RADEON_Q_BIT(unit);
+           vfmt |= RADEON_Q_BIT(unit);
+        }
+        if ( (ctx->Texture.Unit[unit].TexGenEnabled & (R_BIT | Q_BIT)) )
+           vtx |= RADEON_Q_BIT(unit);
+        else if ((VB->TexCoordPtr[unit]->size >= 3) &&
+                 ((ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_CUBE_BIT)) == 0)) {
+           GLuint swaptexmatcol = (VB->TexCoordPtr[unit]->size - 3);
+           if (((rmesa->NeedTexMatrix >> unit) & 1) &&
+                (swaptexmatcol != ((rmesa->TexMatColSwap >> unit) & 1)))
+              radeonUploadTexMatrix( rmesa, unit, swaptexmatcol ) ;
+        }
+        component[nr++] = &rmesa->tcl.tex[unit];
       }
-      component[nr++] = &rmesa->tcl.tex[1];
    }
 
    if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) {
@@ -567,9 +626,12 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
 void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs )
 {
    radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
+   GLuint unit;
 
+#if 0
    if (RADEON_DEBUG & DEBUG_VERTS) 
       _tnl_print_vert_flags( __FUNCTION__, newinputs );
+#endif
 
    if (newinputs & VERT_BIT_POS) 
      radeonReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ );
@@ -582,10 +644,12 @@ void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs )
 
    if (newinputs & VERT_BIT_COLOR1) 
       radeonReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );
+      
+   if (newinputs & VERT_BIT_FOG)
+      radeonReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ );
 
-   if (newinputs & VERT_BIT_TEX0)
-      radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[0], __FUNCTION__ );
-
-   if (newinputs & VERT_BIT_TEX1)
-      radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[1], __FUNCTION__ );
+   for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
+      if (newinputs & VERT_BIT_TEX(unit))
+         radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[unit], __FUNCTION__ );
+   }
 }