Fix crashes during rasterization fallback by avoiding _tnl_need_projected_coords
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_tcl.c
index 9aec22b1a52c1d4142e8081be32320d965c4914c..6eb35c0f27f74c4f89bf8b6d2c7f06f9f95e642c 100644 (file)
@@ -149,6 +149,9 @@ static GLushort *radeonAllocElts( radeonContextPtr rmesa, GLuint nr )
    if (rmesa->dma.flush)
       rmesa->dma.flush( rmesa );
 
+   radeonEnsureCmdBufSpace(rmesa, AOS_BUFSZ(rmesa->tcl.nr_aos_components) +
+                          rmesa->hw.max_state_size + ELTS_BUFSZ(nr));
+
    radeonEmitAOS( rmesa,
                rmesa->tcl.aos_components,
                rmesa->tcl.nr_aos_components, 0 );
@@ -166,7 +169,7 @@ static GLushort *radeonAllocElts( radeonContextPtr rmesa, GLuint nr )
  * discrete and there are no intervening state changes.  (Somewhat
  * duplicates changes to DrawArrays code)
  */
-static void EMIT_PRIM( GLcontext *ctx, 
+static void radeonEmitPrim( GLcontext *ctx, 
                       GLenum prim, 
                       GLuint hwprim, 
                       GLuint start, 
@@ -175,6 +178,9 @@ static void EMIT_PRIM( GLcontext *ctx,
    radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
    radeonTclPrimitive( ctx, prim, hwprim );
    
+   radeonEnsureCmdBufSpace( rmesa, AOS_BUFSZ(rmesa->tcl.nr_aos_components) +
+                           rmesa->hw.max_state_size + VBUF_BUFSZ );
+
    radeonEmitAOS( rmesa,
                  rmesa->tcl.aos_components,
                  rmesa->tcl.nr_aos_components,
@@ -188,7 +194,9 @@ static void EMIT_PRIM( GLcontext *ctx,
                       count - start );
 }
 
-
+#define EMIT_PRIM( ctx, prim, hwprim, start, count ) do {       \
+   radeonEmitPrim( ctx, prim, hwprim, start, count );           \
+   (void) rmesa; } while (0)
 
 /* Try & join small primitives
  */
@@ -208,9 +216,12 @@ static void EMIT_PRIM( GLcontext *ctx,
 #define EMIT_ELT(dest, offset, x) do {                         \
        int off = offset + ( ( (GLuint)dest & 0x2 ) >> 1 );     \
        GLushort *des = (GLushort *)( (GLuint)dest & ~0x2 );    \
-       (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x); } while (0)
+       (des)[ off + 1 - 2 * ( off & 1 ) ] = (GLushort)(x);     \
+       (void)rmesa; } while (0)
 #else
-#define EMIT_ELT(dest, offset, x) (dest)[offset] = (GLushort) (x)
+#define EMIT_ELT(dest, offset, x) do {                         \
+       (dest)[offset] = (GLushort) (x);                        \
+       (void)rmesa; } while (0)
 #endif
 
 #define EMIT_TWO_ELTS(dest, offset, x, y)  *(GLuint *)(dest+offset) = ((y)<<16)|(x);
@@ -282,6 +293,7 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx,
    radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
+   GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0;
    GLuint i;
 
    /* TODO: separate this from the swtnl pipeline 
@@ -292,8 +304,31 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx,
    if (VB->Count == 0)
       return GL_FALSE;
 
-   radeonReleaseArrays( ctx, stage->changed_inputs );
-   radeonEmitArrays( ctx, stage->inputs );
+   /* NOTE: inputs != tnl->render_inputs - these are the untransformed
+    * inputs.
+    */
+   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 ) {
+      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;
+        }
+        inputs |= VERT_BIT_TEX(i);
+      }
+   }
+
+   radeonReleaseArrays( ctx, ~0 );
+   radeonEmitArrays( ctx, inputs );
 
    rmesa->tcl.Elts = VB->Elts;
 
@@ -317,86 +352,15 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx,
 
 
 
-static void radeon_check_tcl_render( GLcontext *ctx,
-                                    struct tnl_pipeline_stage *stage )
-{
-   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
-   GLuint inputs = VERT_BIT_POS;
-
-   if (ctx->RenderMode == GL_RENDER) {
-      /* Make all this event-driven:
-       */
-      if (ctx->Light.Enabled) {
-        inputs |= VERT_BIT_NORMAL;
-
-        if (1 || ctx->Light.ColorMaterialEnabled) {
-           inputs |= VERT_BIT_COLOR0;
-        }
-      }
-      else {
-        inputs |= VERT_BIT_COLOR0;
-        
-        if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
-           inputs |= VERT_BIT_COLOR1;
-        }
-      }
-
-      if (ctx->Texture.Unit[0]._ReallyEnabled) {
-        if (ctx->Texture.Unit[0].TexGenEnabled) {
-           if (rmesa->TexGenNeedNormals[0]) {
-              inputs |= VERT_BIT_NORMAL;
-           }
-        } else {
-           inputs |= VERT_BIT_TEX0;
-        }
-      }
-
-      if (ctx->Texture.Unit[1]._ReallyEnabled) {
-        if (ctx->Texture.Unit[1].TexGenEnabled) {
-           if (rmesa->TexGenNeedNormals[1]) {
-              inputs |= VERT_BIT_NORMAL;
-           }
-        } else {
-           inputs |= VERT_BIT_TEX1;
-        }
-      }
-
-      stage->inputs = inputs;
-      stage->active = 1;
-   }
-   else
-      stage->active = 0;
-}
-
-static void radeon_init_tcl_render( GLcontext *ctx,
-                                   struct tnl_pipeline_stage *stage )
-{
-   stage->check = radeon_check_tcl_render;
-   stage->check( ctx, stage );
-}
-
-static void dtr( struct tnl_pipeline_stage *stage )
-{
-   (void)stage;
-}
-
-
 /* Initial state for tcl stage.  
  */
 const struct tnl_pipeline_stage _radeon_tcl_stage =
 {
    "radeon render",
-   (_DD_NEW_SEPARATE_SPECULAR |
-    _NEW_LIGHT|
-    _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 */
-   radeon_init_tcl_render,     /* check - initially set to alloc data */
+   NULL,
+   NULL,
+   NULL,
+   NULL,
    radeon_run_tcl_render       /* run */
 };
 
@@ -461,7 +425,7 @@ static void transition_to_hwtnl( GLcontext *ctx )
    if ( rmesa->dma.flush )                     
       rmesa->dma.flush( rmesa );       
 
-   rmesa->dma.flush = 0;
+   rmesa->dma.flush = NULL;
    rmesa->swtcl.vertex_format = 0;
    
    if (rmesa->swtcl.indexed_verts.buf)