r200: fix some cube map issues
[mesa.git] / src / mesa / drivers / dri / savage / savagerender.c
index 50ec9eac68530037847f1c7b0cd299ae16e2a048..32c74f9467e6d0994fcbf5483ad483b376dfbcbc 100644 (file)
  * dma buffers.  Use strip/fan hardware primitives where possible.
  * Simulate missing primitives with indexed vertices.
  */
-#include "glheader.h"
-#include "context.h"
-#include "macros.h"
-#include "imports.h"
-#include "mtypes.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
 
 #include "tnl/t_context.h"
 
@@ -54,7 +54,7 @@
 #define HAVE_QUADS       0
 #define HAVE_QUAD_STRIPS 0
 
-#define HAVE_ELTS        0     /* for now */
+#define HAVE_ELTS        1
 
 #define LOCAL_VARS savageContextPtr imesa = SAVAGE_CONTEXT(ctx) 
 #define INIT( prim ) do {                                              \
@@ -66,7 +66,8 @@
    case GL_TRIANGLE_FAN:   imesa->HwPrim = SAVAGE_PRIM_TRIFAN; break;  \
    }                                                                   \
 } while (0)
-#define FLUSH()                savageFlushVertices(imesa)
+#define FLUSH()                savageFlushElts(imesa), savageFlushVertices(imesa)
+
 #define GET_CURRENT_VB_MAX_VERTS() \
    ((imesa->bufferSize/4 - imesa->vtxBuf->used) / imesa->HwVertexSize)
 #define GET_SUBSEQUENT_VB_MAX_VERTS() \
 #define EMIT_VERTS( ctx, j, nr, buf ) \
        _tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf )
 
+#define ELTS_VARS( buf ) GLushort *dest = buf, firstElt = imesa->firstElt
+#define ELT_INIT( prim ) INIT(prim)
+
+/* (size - used - 1 qword for drawing command) * 4 elts per qword */
+#define GET_CURRENT_VB_MAX_ELTS() \
+   ((imesa->cmdBuf.size - (imesa->cmdBuf.write - imesa->cmdBuf.base) - 1)*4)
+/* (size - space for initial state - 1 qword for drawing command) * 4 elts
+ * imesa is not defined in validate_render :( */
+#define GET_SUBSEQUENT_VB_MAX_ELTS()                                   \
+   ((SAVAGE_CONTEXT(ctx)->cmdBuf.size -                                \
+     (SAVAGE_CONTEXT(ctx)->cmdBuf.start -                              \
+      SAVAGE_CONTEXT(ctx)->cmdBuf.base) - 1)*4)
+
+#define ALLOC_ELTS(nr) savageAllocElts(imesa, nr)
+#define EMIT_ELT(offset, x) do {                                       \
+   (dest)[offset] = (GLushort) ((x)+firstElt);                         \
+} while (0)
+#define EMIT_TWO_ELTS(offset, x, y) do {                               \
+   *(GLuint *)(dest + offset) = (((y)+firstElt) << 16) |               \
+                               ((x)+firstElt);                         \
+} while (0)
+
+#define INCR_ELTS( nr ) dest += nr
+#define ELTPTR dest
+#define RELEASE_ELT_VERTS() \
+   savageReleaseIndexedVerts(imesa)
+
+#define EMIT_INDEXED_VERTS( ctx, start, count ) do {                   \
+   GLuint *buf = savageAllocIndexedVerts(imesa, count-start);          \
+   EMIT_VERTS(ctx, start, count-start, buf);                           \
+} while (0)
+
 #define TAG(x) savage_##x
 #include "tnl_dd/t_dd_dmatmp.h"
 
@@ -114,20 +147,25 @@ static GLboolean savage_run_render( GLcontext *ctx,
    savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb; 
-   tnl_render_func *tab;
+   tnl_render_func *tab, *tab_elts;
    GLboolean valid;
    GLuint i;
 
+   if (savageHaveIndexedVerts(imesa))
+      savageReleaseIndexedVerts(imesa);
+
    if (imesa->savageScreen->chipset < S3_SAVAGE4 &&
        (ctx->_TriangleCaps & DD_FLATSHADE)) {
       tab = savage_flat_render_tab_verts_s3d;
+      tab_elts = savage_flat_render_tab_elts_s3d;
       valid = savage_flat_validate_render_s3d( ctx, VB );
    } else {
       tab = savage_render_tab_verts;
+      tab_elts = savage_render_tab_elts;
       valid = savage_validate_render( ctx, VB );
    }
 
-   /* Don't handle clipping or indexed vertices or vertex manipulations.
+   /* Don't handle clipping or vertex manipulations.
     */
    if (imesa->RenderIndex != 0 || !valid) {
       return GL_TRUE;
@@ -135,7 +173,7 @@ static GLboolean savage_run_render( GLcontext *ctx,
    
    tnl->Driver.Render.Start( ctx );
    /* Check RenderIndex again. The ptexHack is detected late in RenderStart.
-    * Also check for fallbacks detected late.
+    * Also check for ptex fallbacks detected late.
     */
    if (imesa->RenderIndex != 0 || imesa->Fallback != 0) {
       return GL_TRUE;
@@ -144,11 +182,23 @@ static GLboolean savage_run_render( GLcontext *ctx,
    /* setup for hardware culling */
    imesa->raster_primitive = GL_TRIANGLES;
    imesa->new_state |= SAVAGE_NEW_CULL;
+
+   /* update and emit state */
    savageDDUpdateHwState(ctx);
+   savageEmitChangedState(imesa);
+
+   if (VB->Elts) {
+      tab = tab_elts;
+      if (!savageHaveIndexedVerts(imesa)) {
+        if (VB->Count > GET_SUBSEQUENT_VB_MAX_VERTS())
+           return GL_TRUE;
+        EMIT_INDEXED_VERTS(ctx, 0, VB->Count);
+      }
+   }
 
    for (i = 0 ; i < VB->PrimitiveCount ; i++)
    {
-      GLuint prim = VB->Primitive[i].mode;
+      GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);
       GLuint start = VB->Primitive[i].start;
       GLuint length = VB->Primitive[i].count;
 
@@ -161,43 +211,13 @@ static GLboolean savage_run_render( GLcontext *ctx,
    return GL_FALSE;            /* finished the pipe */
 }
 
-static void savage_check_render( GLcontext *ctx,
-                                struct tnl_pipeline_stage *stage )
-{
-   __DRIscreenPrivate *driScrnPriv =
-      SAVAGE_CONTEXT(ctx)->savageScreen->driScrnPriv;
-   stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
-   /* This hack will go away when we depend on 2.2.x for ELTS. */
-   if (driScrnPriv->drmMinor <= 1 && driScrnPriv->drmPatch < 3) {
-      static GLboolean firstTime = GL_TRUE;
-      stage->active = GL_FALSE;
-      if (firstTime) {
-        fprintf (stderr,
-                 "*** Disabling fast path because your DRM version is buggy.\n"
-                 "*** You need at least Savage DRM version 2.1.3.\n");
-        firstTime = GL_FALSE;
-      }
-   }
-}
-
-static void dtr( struct tnl_pipeline_stage *stage )
-{
-   (void)stage;
-}
-
-const struct tnl_pipeline_stage _savage_render_stage = 
+struct tnl_pipeline_stage _savage_render_stage = 
 { 
    "savage render",
-   (_DD_NEW_SEPARATE_SPECULAR |
-    _NEW_TEXTURE|
-    _NEW_FOG|
-    _NEW_RENDERMODE),          /* re-check (new inputs) */
-   0,                          /* re-run (always runs) */
-   GL_TRUE,                    /* active */
-   0, 0,                       /* inputs (set in check_render), outputs */
-   0, 0,                       /* changed_inputs, private */
-   dtr,                                /* destructor */
-   savage_check_render,                /* check - initially set to alloc data */
+   NULL,
+   NULL,
+   NULL,
+   NULL,
    savage_run_render           /* run */
 };
 
@@ -206,6 +226,7 @@ const struct tnl_pipeline_stage _savage_render_stage =
 /*         Pipeline stage for texture coordinate normalization        */
 /**********************************************************************/
 struct texnorm_stage_data {
+   GLboolean active;
    GLvector4f texcoord[MAX_TEXTURE_UNITS];
 };
 
@@ -221,61 +242,63 @@ static GLboolean run_texnorm_stage( GLcontext *ctx,
    struct vertex_buffer *VB = &tnl->vb;
    GLuint i;
 
-   if (imesa->Fallback)
+   if (imesa->Fallback || !store->active)
       return GL_TRUE;
 
    for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
-      if (!(stage->inputs & stage->changed_inputs & VERT_BIT_TEX(i)) ||
-         VB->TexCoordPtr[i]->size == 4)
-        /* Never try to normalize homogenous tex coords! */
-        continue;
-
-      GLuint reallyEnabled = ctx->Texture.Unit[i]._ReallyEnabled;
-      struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
-      GLboolean normalizeS = (texObj->WrapS == GL_REPEAT);
-      GLboolean normalizeT = (reallyEnabled & TEXTURE_2D_BIT) &&
-        (texObj->WrapT == GL_REPEAT);
-      GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data;
-      GLint instride = VB->TexCoordPtr[i]->stride;
-      GLfloat (*out)[4] = store->texcoord[i].data;
-      GLint j;
-
-      if (normalizeS && normalizeT) {
-        /* take first texcoords as rough estimate of mean value */
-        GLfloat correctionS = -floor(in[0]+0.5);
-        GLfloat correctionT = -floor(in[1]+0.5);
-        for (j = 0; j < VB->Count; ++j) {
-           out[j][0] = in[0] + correctionS;
-           out[j][1] = in[1] + correctionT;
-           in = (GLfloat *)((GLubyte *)in + instride);
-        }
-      } else if (normalizeS) {
-        /* take first texcoords as rough estimate of mean value */
-        GLfloat correctionS = -floor(in[0]+0.5);
-        if (reallyEnabled & TEXTURE_2D_BIT) {
-           for (j = 0; j < VB->Count; ++j) {
-              out[j][0] = in[0] + correctionS;
-              out[j][1] = in[1];
-              in = (GLfloat *)((GLubyte *)in + instride);
-           }
-        } else {
-           for (j = 0; j < VB->Count; ++j) {
-              out[j][0] = in[0] + correctionS;
-              in = (GLfloat *)((GLubyte *)in + instride);
-           }
-        }
-      } else if (normalizeT) {
-        /* take first texcoords as rough estimate of mean value */
-        GLfloat correctionT = -floor(in[1]+0.5);
-        for (j = 0; j < VB->Count; ++j) {
-           out[j][0] = in[0];
-           out[j][1] = in[1] + correctionT;
-           in = (GLfloat *)((GLubyte *)in + instride);
-        }
+      const GLbitfield reallyEnabled = ctx->Texture.Unit[i]._ReallyEnabled;
+      if (reallyEnabled) {
+         const struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
+         const GLboolean normalizeS = (texObj->WrapS == GL_REPEAT);
+         const GLboolean normalizeT = (reallyEnabled & TEXTURE_2D_BIT) &&
+            (texObj->WrapT == GL_REPEAT);
+         const GLfloat *in = (GLfloat *)VB->TexCoordPtr[i]->data;
+         const GLint instride = VB->TexCoordPtr[i]->stride;
+         GLfloat (*out)[4] = store->texcoord[i].data;
+         GLint j;
+
+         if (!ctx->Texture.Unit[i]._ReallyEnabled ||
+             VB->TexCoordPtr[i]->size == 4)
+            /* Never try to normalize homogenous tex coords! */
+            continue;
+
+         if (normalizeS && normalizeT) {
+            /* take first texcoords as rough estimate of mean value */
+            GLfloat correctionS = -floor(in[0]+0.5);
+            GLfloat correctionT = -floor(in[1]+0.5);
+            for (j = 0; j < VB->Count; ++j) {
+               out[j][0] = in[0] + correctionS;
+               out[j][1] = in[1] + correctionT;
+               in = (GLfloat *)((GLubyte *)in + instride);
+            }
+         } else if (normalizeS) {
+            /* take first texcoords as rough estimate of mean value */
+            GLfloat correctionS = -floor(in[0]+0.5);
+            if (reallyEnabled & TEXTURE_2D_BIT) {
+               for (j = 0; j < VB->Count; ++j) {
+                  out[j][0] = in[0] + correctionS;
+                  out[j][1] = in[1];
+                  in = (GLfloat *)((GLubyte *)in + instride);
+               }
+            } else {
+               for (j = 0; j < VB->Count; ++j) {
+                  out[j][0] = in[0] + correctionS;
+                  in = (GLfloat *)((GLubyte *)in + instride);
+               }
+            }
+         } else if (normalizeT) {
+            /* take first texcoords as rough estimate of mean value */
+            GLfloat correctionT = -floor(in[1]+0.5);
+            for (j = 0; j < VB->Count; ++j) {
+               out[j][0] = in[0];
+               out[j][1] = in[1] + correctionT;
+               in = (GLfloat *)((GLubyte *)in + instride);
+            }
+         }
+
+         if (normalizeS || normalizeT)
+            VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i];
       }
-
-      if (normalizeS || normalizeT)
-        VB->AttribPtr[VERT_ATTRIB_TEX0+i] = VB->TexCoordPtr[i] = &store->texcoord[i];
    }
 
    return GL_TRUE;
@@ -297,16 +320,14 @@ static GLboolean alloc_texnorm_data( GLcontext *ctx,
 
    for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
       _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );
-
-   /* Now run the stage.
-    */
-   stage->run = run_texnorm_stage;
-   return stage->run( ctx, stage );
+   
+   return GL_TRUE;
 }
 
-static void check_texnorm( GLcontext *ctx,
-                          struct tnl_pipeline_stage *stage )
+static void validate_texnorm( GLcontext *ctx,
+                             struct tnl_pipeline_stage *stage )
 {
+   struct texnorm_stage_data *store = TEXNORM_STAGE_DATA(stage);
    GLuint flags = 0;
 
    if (((ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) &&
@@ -321,9 +342,7 @@ static void check_texnorm( GLcontext *ctx,
        (ctx->Texture.Unit[1]._Current->WrapT == GL_REPEAT)))
       flags |= VERT_BIT_TEX1;
 
-   stage->inputs = flags;
-   stage->outputs = flags;
-   stage->active = (flags != 0);
+   store->active = (flags != 0);
 }
 
 static void free_texnorm_data( struct tnl_pipeline_stage *stage )
@@ -340,17 +359,12 @@ static void free_texnorm_data( struct tnl_pipeline_stage *stage )
    }
 }
 
-const struct tnl_pipeline_stage _savage_texnorm_stage =
+struct tnl_pipeline_stage _savage_texnorm_stage =
 {
    "savage texture coordinate normalization stage", /* name */
-   _NEW_TEXTURE,       /* check_state */
-   _NEW_TEXTURE,       /* run_state */
-   GL_TRUE,                            /* active? */
-   0,                                  /* inputs */
-   0,                                  /* outputs */
-   0,                                  /* changed_inputs */
    NULL,                               /* private data */
-   free_texnorm_data,                  /* destructor */
-   check_texnorm,                      /* check */
    alloc_texnorm_data,                 /* run -- initially set to init */
+   free_texnorm_data,                  /* destructor */
+   validate_texnorm,
+   run_texnorm_stage
 };