fix typo
[mesa.git] / src / mesa / swrast / s_triangle.c
index 8c340c0b0dd3d9dde4d20280fcebe4cb0b1371a2..ebbba34af5c12b0f126c95a6cd8ed57e9984aa57 100644 (file)
@@ -1,10 +1,8 @@
-/* $Id: s_triangle.c,v 1.63 2002/10/24 23:57:24 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
- * Version:  4.1
+ * Version:  5.1
  *
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -36,7 +34,6 @@
 #include "colormac.h"
 #include "imports.h"
 #include "macros.h"
-#include "mmath.h"
 #include "texformat.h"
 #include "teximage.h"
 #include "texstate.h"
@@ -52,7 +49,7 @@
 /*
  * Just used for feedback mode.
  */
-GLboolean _mesa_cull_triangle( GLcontext *ctx,
+GLboolean _swrast_culltriangle( GLcontext *ctx,
                            const SWvertex *v0,
                            const SWvertex *v1,
                            const SWvertex *v2 )
@@ -63,7 +60,7 @@ GLboolean _mesa_cull_triangle( GLcontext *ctx,
    GLfloat fy = v2->win[1] - v0->win[1];
    GLfloat c = ex*fy-ey*fx;
 
-   if (c * SWRAST_CONTEXT(ctx)->_backface_sign > 0)
+   if (c * SWRAST_CONTEXT(ctx)->_BackfaceSign > 0)
       return 0;
 
    return 1;
@@ -74,59 +71,39 @@ GLboolean _mesa_cull_triangle( GLcontext *ctx,
 /*
  * Render a flat-shaded color index triangle.
  */
-static void flat_ci_triangle( GLcontext *ctx,
-                             const SWvertex *v0,
-                             const SWvertex *v1,
-                             const SWvertex *v2 )
-{
+#define NAME flat_ci_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
-
-#define SETUP_CODE                                     \
-   span.interpMask |= SPAN_INDEX;                      \
-   span.index = IntToFixed(v2->index);                 \
+#define SETUP_CODE                     \
+   span.interpMask |= SPAN_INDEX;      \
+   span.index = IntToFixed(v2->index); \
    span.indexStep = 0;
-
-#define RENDER_SPAN( span )  _mesa_write_index_span(ctx, &span);
-
+#define RENDER_SPAN( span )  _swrast_write_index_span(ctx, &span);
 #include "s_tritemp.h"
-}
 
 
 
 /*
  * Render a smooth-shaded color index triangle.
  */
-static void smooth_ci_triangle( GLcontext *ctx,
-                               const SWvertex *v0,
-                               const SWvertex *v1,
-                               const SWvertex *v2 )
-{
+#define NAME smooth_ci_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
 #define INTERP_INDEX 1
-
-#define RENDER_SPAN( span )  _mesa_write_index_span(ctx, &span);
-
+#define RENDER_SPAN( span )  _swrast_write_index_span(ctx, &span);
 #include "s_tritemp.h"
-}
 
 
 
 /*
  * Render a flat-shaded RGBA triangle.
  */
-static void flat_rgba_triangle( GLcontext *ctx,
-                               const SWvertex *v0,
-                               const SWvertex *v1,
-                               const SWvertex *v2 )
-{
+#define NAME flat_rgba_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-
 #define SETUP_CODE                             \
-   ASSERT(ctx->Texture._EnabledUnits == 0);    \
+   ASSERT(ctx->Texture._EnabledCoordUnits == 0);\
    ASSERT(ctx->Light.ShadeModel==GL_FLAT);     \
    span.interpMask |= SPAN_RGBA;               \
    span.red = ChanToFixed(v2->color[0]);       \
@@ -137,41 +114,29 @@ static void flat_rgba_triangle( GLcontext *ctx,
    span.greenStep = 0;                         \
    span.blueStep = 0;                          \
    span.alphaStep = 0;
-
-#define RENDER_SPAN( span )  _mesa_write_rgba_span(ctx, &span);
-
+#define RENDER_SPAN( span )  _swrast_write_rgba_span(ctx, &span);
 #include "s_tritemp.h"
-}
 
 
 
 /*
  * Render a smooth-shaded RGBA triangle.
  */
-static void smooth_rgba_triangle( GLcontext *ctx,
-                                 const SWvertex *v0,
-                                 const SWvertex *v1,
-                                 const SWvertex *v2 )
-{
-
+#define NAME smooth_rgba_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
-
 #define SETUP_CODE                             \
    {                                           \
       /* texturing must be off */              \
-      ASSERT(ctx->Texture._EnabledUnits == 0); \
+      ASSERT(ctx->Texture._EnabledCoordUnits == 0);    \
       ASSERT(ctx->Light.ShadeModel==GL_SMOOTH);        \
    }
-
-#define RENDER_SPAN( span )  _mesa_write_rgba_span(ctx, &span);
-
+#define RENDER_SPAN( span )  _swrast_write_rgba_span(ctx, &span);
 #include "s_tritemp.h"
 
-}
 
 
 /*
@@ -180,11 +145,7 @@ static void smooth_rgba_triangle( GLcontext *ctx,
  *
  * No fog.
  */
-static void simple_textured_triangle( GLcontext *ctx,
-                                     const SWvertex *v0,
-                                     const SWvertex *v1,
-                                     const SWvertex *v2 )
-{
+#define NAME simple_textured_triangle
 #define INTERP_INT_TEX 1
 #define S_SCALE twidth
 #define T_SCALE theight
@@ -193,12 +154,12 @@ static void simple_textured_triangle( GLcontext *ctx,
    SWcontext *swrast = SWRAST_CONTEXT(ctx);                             \
    struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D;     \
    const GLint b = obj->BaseLevel;                                     \
-   const GLfloat twidth = (GLfloat) obj->Image[b]->Width;              \
-   const GLfloat theight = (GLfloat) obj->Image[b]->Height;            \
-   const GLint twidth_log2 = obj->Image[b]->WidthLog2;                 \
-   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
-   const GLint smask = obj->Image[b]->Width - 1;                       \
-   const GLint tmask = obj->Image[b]->Height - 1;                      \
+   const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;           \
+   const GLfloat theight = (GLfloat) obj->Image[0][b]->Height;         \
+   const GLint twidth_log2 = obj->Image[0][b]->WidthLog2;                      \
+   const GLchan *texture = (const GLchan *) obj->Image[0][b]->Data;    \
+   const GLint smask = obj->Image[0][b]->Width - 1;                    \
+   const GLint tmask = obj->Image[0][b]->Height - 1;                   \
    if (!texture) {                                                     \
       /* this shouldn't happen */                                      \
       return;                                                          \
@@ -222,9 +183,8 @@ static void simple_textured_triangle( GLcontext *ctx,
    (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y,       \
                                   (CONST GLchan (*)[3]) span.array->rgb,\
                                   NULL );
-
 #include "s_tritemp.h"
-}
+
 
 
 /*
@@ -234,11 +194,7 @@ static void simple_textured_triangle( GLcontext *ctx,
  *
  * No fog.
  */
-static void simple_z_textured_triangle( GLcontext *ctx,
-                                       const SWvertex *v0,
-                                       const SWvertex *v1,
-                                       const SWvertex *v2 )
-{
+#define NAME simple_z_textured_triangle
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_INT_TEX 1
@@ -249,12 +205,12 @@ static void simple_z_textured_triangle( GLcontext *ctx,
    SWcontext *swrast = SWRAST_CONTEXT(ctx);                             \
    struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D;     \
    const GLint b = obj->BaseLevel;                                     \
-   const GLfloat twidth = (GLfloat) obj->Image[b]->Width;              \
-   const GLfloat theight = (GLfloat) obj->Image[b]->Height;            \
-   const GLint twidth_log2 = obj->Image[b]->WidthLog2;                 \
-   const GLchan *texture = (const GLchan *) obj->Image[b]->Data;       \
-   const GLint smask = obj->Image[b]->Width - 1;                       \
-   const GLint tmask = obj->Image[b]->Height - 1;                      \
+   const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;           \
+   const GLfloat theight = (GLfloat) obj->Image[0][b]->Height;         \
+   const GLint twidth_log2 = obj->Image[0][b]->WidthLog2;                      \
+   const GLchan *texture = (const GLchan *) obj->Image[0][b]->Data;    \
+   const GLint smask = obj->Image[0][b]->Width - 1;                    \
+   const GLint tmask = obj->Image[0][b]->Height - 1;                   \
    if (!texture) {                                                     \
       /* this shouldn't happen */                                      \
       return;                                                          \
@@ -287,9 +243,8 @@ static void simple_z_textured_triangle( GLcontext *ctx,
    (*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y,       \
                                   (CONST GLchan (*)[3]) span.array->rgb,\
                                   span.array->mask );
-
 #include "s_tritemp.h"
-}
+
 
 
 #if CHAN_TYPE != GL_FLOAT
@@ -477,7 +432,8 @@ affine_span(GLcontext *ctx, struct sw_span *span,
             SPAN_NEAREST(NEAREST_RGB;ADD,3);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR");
+            return;
          }
          break;
       case GL_RGBA:
@@ -498,7 +454,8 @@ affine_span(GLcontext *ctx, struct sw_span *span,
             SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR");
+            return;
          }
          break;
       }
@@ -524,7 +481,8 @@ affine_span(GLcontext *ctx, struct sw_span *span,
             SPAN_LINEAR(LINEAR_RGB;ADD,3);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR");
+            return;
          }
          break;
       case GL_RGBA:
@@ -545,14 +503,16 @@ affine_span(GLcontext *ctx, struct sw_span *span,
             SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
             break;
          default:
-            abort();
-         }                 break;
+            _mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR");
+            return;
+         }
+         break;
       }
       break;
    }
    span->interpMask &= ~SPAN_RGBA;
    ASSERT(span->arrayMask & SPAN_RGBA);
-   _mesa_write_rgba_span(ctx, span);
+   _swrast_write_rgba_span(ctx, span);
 
 #undef SPAN_NEAREST
 #undef SPAN_LINEAR
@@ -563,11 +523,7 @@ affine_span(GLcontext *ctx, struct sw_span *span,
 /*
  * Render an RGB/RGBA textured triangle without perspective correction.
  */
-static void affine_textured_triangle( GLcontext *ctx,
-                                     const SWvertex *v0,
-                                     const SWvertex *v1,
-                                     const SWvertex *v2 )
-{
+#define NAME affine_textured_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -582,13 +538,13 @@ static void affine_textured_triangle( GLcontext *ctx,
    struct gl_texture_unit *unit = ctx->Texture.Unit+0;                 \
    struct gl_texture_object *obj = unit->Current2D;                    \
    const GLint b = obj->BaseLevel;                                     \
-   const GLfloat twidth = (GLfloat) obj->Image[b]->Width;              \
-   const GLfloat theight = (GLfloat) obj->Image[b]->Height;            \
-   info.texture = (const GLchan *) obj->Image[b]->Data;                        \
-   info.twidth_log2 = obj->Image[b]->WidthLog2;                                \
-   info.smask = obj->Image[b]->Width - 1;                              \
-   info.tmask = obj->Image[b]->Height - 1;                             \
-   info.format = obj->Image[b]->Format;                                        \
+   const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width;           \
+   const GLfloat theight = (GLfloat) obj->Image[0][b]->Height;         \
+   info.texture = (const GLchan *) obj->Image[0][b]->Data;                     \
+   info.twidth_log2 = obj->Image[0][b]->WidthLog2;                             \
+   info.smask = obj->Image[0][b]->Width - 1;                           \
+   info.tmask = obj->Image[0][b]->Height - 1;                          \
+   info.format = obj->Image[0][b]->Format;                                     \
    info.filter = obj->MinFilter;                                       \
    info.envmode = unit->EnvMode;                                       \
    span.arrayMask |= SPAN_RGBA;                                                \
@@ -609,29 +565,27 @@ static void affine_textured_triangle( GLcontext *ctx,
    case GL_ALPHA:                                                      \
    case GL_LUMINANCE:                                                  \
    case GL_INTENSITY:                                                  \
-      info.tbytesline = obj->Image[b]->Width;                          \
+      info.tbytesline = obj->Image[0][b]->Width;                               \
       break;                                                           \
    case GL_LUMINANCE_ALPHA:                                            \
-      info.tbytesline = obj->Image[b]->Width * 2;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 2;                   \
       break;                                                           \
    case GL_RGB:                                                                \
-      info.tbytesline = obj->Image[b]->Width * 3;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 3;                   \
       break;                                                           \
    case GL_RGBA:                                                       \
-      info.tbytesline = obj->Image[b]->Width * 4;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 4;                   \
       break;                                                           \
    default:                                                            \
       _mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\
       return;                                                          \
    }                                                                   \
-   info.tsize = obj->Image[b]->Height * info.tbytesline;
+   info.tsize = obj->Image[0][b]->Height * info.tbytesline;
 
 #define RENDER_SPAN( span )   affine_span(ctx, &span, &info);
 
 #include "s_tritemp.h"
 
-}
-
 
 
 struct persp_info
@@ -750,7 +704,8 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
             SPAN_NEAREST(NEAREST_RGB;ADD,3);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR");
+            return;
          }
          break;
       case GL_RGBA:
@@ -771,7 +726,8 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
             SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR");
+            return;
          }
          break;
       }
@@ -795,7 +751,8 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
             SPAN_LINEAR(LINEAR_RGB;ADD,3);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR");
+            return;
          }
          break;
       case GL_RGBA:
@@ -816,7 +773,8 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
             SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
             break;
          default:
-            abort();
+            _mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR");
+            return;
          }
          break;
       }
@@ -824,7 +782,7 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
    }
    
    ASSERT(span->arrayMask & SPAN_RGBA);
-   _mesa_write_rgba_span(ctx, span);
+   _swrast_write_rgba_span(ctx, span);
 
 #undef SPAN_NEAREST
 #undef SPAN_LINEAR
@@ -837,11 +795,7 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
  * by interpolated Q/W comes out right.
  *
  */
-static void persp_textured_triangle( GLcontext *ctx,
-                                    const SWvertex *v0,
-                                    const SWvertex *v1,
-                                    const SWvertex *v2 )
-{
+#define NAME persp_textured_triangle
 #define INTERP_Z 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
@@ -854,11 +808,11 @@ static void persp_textured_triangle( GLcontext *ctx,
    const struct gl_texture_unit *unit = ctx->Texture.Unit+0;           \
    const struct gl_texture_object *obj = unit->Current2D;              \
    const GLint b = obj->BaseLevel;                                     \
-   info.texture = (const GLchan *) obj->Image[b]->Data;                        \
-   info.twidth_log2 = obj->Image[b]->WidthLog2;                                \
-   info.smask = obj->Image[b]->Width - 1;                              \
-   info.tmask = obj->Image[b]->Height - 1;                             \
-   info.format = obj->Image[b]->Format;                                        \
+   info.texture = (const GLchan *) obj->Image[0][b]->Data;                     \
+   info.twidth_log2 = obj->Image[0][b]->WidthLog2;                             \
+   info.smask = obj->Image[0][b]->Width - 1;                           \
+   info.tmask = obj->Image[0][b]->Height - 1;                          \
+   info.format = obj->Image[0][b]->Format;                                     \
    info.filter = obj->MinFilter;                                       \
    info.envmode = unit->EnvMode;                                       \
                                                                        \
@@ -878,22 +832,22 @@ static void persp_textured_triangle( GLcontext *ctx,
    case GL_ALPHA:                                                      \
    case GL_LUMINANCE:                                                  \
    case GL_INTENSITY:                                                  \
-      info.tbytesline = obj->Image[b]->Width;                          \
+      info.tbytesline = obj->Image[0][b]->Width;                               \
       break;                                                           \
    case GL_LUMINANCE_ALPHA:                                            \
-      info.tbytesline = obj->Image[b]->Width * 2;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 2;                   \
       break;                                                           \
    case GL_RGB:                                                                \
-      info.tbytesline = obj->Image[b]->Width * 3;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 3;                   \
       break;                                                           \
    case GL_RGBA:                                                       \
-      info.tbytesline = obj->Image[b]->Width * 4;                      \
+      info.tbytesline = obj->Image[0][b]->Width * 4;                   \
       break;                                                           \
    default:                                                            \
       _mesa_problem(NULL, "Bad texture format in persp_textured_triangle");\
       return;                                                          \
    }                                                                   \
-   info.tsize = obj->Image[b]->Height * info.tbytesline;
+   info.tsize = obj->Image[0][b]->Height * info.tbytesline;
 
 #define RENDER_SPAN( span )                    \
    span.interpMask &= ~SPAN_RGBA;              \
@@ -902,8 +856,6 @@ static void persp_textured_triangle( GLcontext *ctx,
 
 #include "s_tritemp.h"
 
-}
-
 
 #endif /* CHAN_BITS != GL_FLOAT */
 
@@ -914,23 +866,17 @@ static void persp_textured_triangle( GLcontext *ctx,
  * Render a smooth-shaded, textured, RGBA triangle.
  * Interpolate S,T,R with perspective correction, w/out mipmapping.
  */
-static void general_textured_triangle( GLcontext *ctx,
-                                      const SWvertex *v0,
-                                      const SWvertex *v1,
-                                      const SWvertex *v2 )
-{
+#define NAME general_textured_triangle
 #define INTERP_Z 1
+#define INTERP_W 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_RGB 1
 #define INTERP_SPEC 1
 #define INTERP_ALPHA 1
 #define INTERP_TEX 1
-
-#define RENDER_SPAN( span )   _mesa_write_texture_span(ctx, &span);
-
+#define RENDER_SPAN( span )   _swrast_write_texture_span(ctx, &span);
 #include "s_tritemp.h"
-}
 
 
 
@@ -939,59 +885,50 @@ static void general_textured_triangle( GLcontext *ctx,
  * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates.
  * Yup, it's slow.
  */
-static void
-multitextured_triangle( GLcontext *ctx,
-                        const SWvertex *v0,
-                        const SWvertex *v1,
-                        const SWvertex *v2 )
-{
-
+#define NAME multitextured_triangle
 #define INTERP_Z 1
+#define INTERP_W 1
 #define INTERP_FOG 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 #define INTERP_RGB 1
 #define INTERP_ALPHA 1
 #define INTERP_SPEC 1
 #define INTERP_MULTITEX 1
-
-#define RENDER_SPAN( span )   _mesa_write_texture_span(ctx, &span);
-
+#define RENDER_SPAN( span )   _swrast_write_texture_span(ctx, &span);
 #include "s_tritemp.h"
 
-}
 
 
-static void occlusion_zless_triangle( GLcontext *ctx,
-                                     const SWvertex *v0,
-                                     const SWvertex *v1,
-                                     const SWvertex *v2 )
-{
-   if (ctx->OcclusionResult) {
-      return;
-   }
-
+/*
+ * Special tri function for occlusion testing
+ */
+#define NAME occlusion_zless_triangle
 #define DO_OCCLUSION_TEST
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-
+#define SETUP_CODE                                             \
+   if (ctx->OcclusionResult && !ctx->Occlusion.Active) {       \
+      return;                                                  \
+   }
 #define RENDER_SPAN( span )                            \
    GLuint i;                                           \
    for (i = 0; i < span.end; i++) {                    \
       GLdepth z = FixedToDepth(span.z);                        \
       if (z < zRow[i]) {                               \
          ctx->OcclusionResult = GL_TRUE;               \
-         return;                                       \
+         ctx->Occlusion.PassedCounter++;               \
       }                                                        \
       span.z += span.zStep;                            \
    }
-
 #include "s_tritemp.h"
-}
 
-static void nodraw_triangle( GLcontext *ctx,
-                            const SWvertex *v0,
-                            const SWvertex *v1,
-                            const SWvertex *v2 )
+
+
+static void
+nodraw_triangle( GLcontext *ctx,
+                 const SWvertex *v0,
+                 const SWvertex *v1,
+                 const SWvertex *v2 )
 {
    (void) (ctx && v0 && v1 && v2);
 }
@@ -1095,12 +1032,13 @@ _swrast_choose_triangle( GLcontext *ctx )
    if (ctx->RenderMode==GL_RENDER) {
 
       if (ctx->Polygon.SmoothFlag) {
-         _mesa_set_aa_triangle_function(ctx);
+         _swrast_set_aa_triangle_function(ctx);
          ASSERT(swrast->Triangle);
          return;
       }
 
-      if (ctx->Depth.OcclusionTest &&
+      /* special case for occlusion testing */
+      if ((ctx->Depth.OcclusionTest || ctx->Occlusion.Active) &&
           ctx->Depth.Test &&
           ctx->Depth.Mask == GL_FALSE &&
           ctx->Depth.Func == GL_LESS &&
@@ -1117,24 +1055,26 @@ _swrast_choose_triangle( GLcontext *ctx )
          }
       }
 
-      if (ctx->Texture._EnabledUnits) {
+      if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram.Enabled) {
          /* Ugh, we do a _lot_ of tests to pick the best textured tri func */
         const struct gl_texture_object *texObj2D;
          const struct gl_texture_image *texImg;
          GLenum minFilter, magFilter, envMode;
          GLint format;
          texObj2D = ctx->Texture.Unit[0].Current2D;
-         texImg = texObj2D ? texObj2D->Image[texObj2D->BaseLevel] : NULL;
+         texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL;
          format = texImg ? texImg->TexFormat->MesaFormat : -1;
          minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0;
          magFilter = texObj2D ? texObj2D->MagFilter : (GLenum) 0;
          envMode = ctx->Texture.Unit[0].EnvMode;
 
-         /* First see if we can used an optimized 2-D texture function */
-         if (ctx->Texture._EnabledUnits == 1
+         /* First see if we can use an optimized 2-D texture function */
+         if (ctx->Texture._EnabledCoordUnits == 1
+             && !ctx->FragmentProgram.Enabled
              && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
              && texObj2D->WrapS==GL_REPEAT
             && texObj2D->WrapT==GL_REPEAT
+             && texObj2D->_IsPowerOfTwo
              && texImg->Border==0
              && texImg->Width == texImg->RowStride
              && (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
@@ -1175,7 +1115,7 @@ _swrast_choose_triangle( GLcontext *ctx )
         }
          else {
             /* general case textured triangles */
-            if (ctx->Texture._EnabledUnits > 1) {
+            if (ctx->Texture._EnabledCoordUnits > 1) {
                USE(multitextured_triangle);
             }
             else {
@@ -1184,7 +1124,7 @@ _swrast_choose_triangle( GLcontext *ctx )
          }
       }
       else {
-         ASSERT(!ctx->Texture._EnabledUnits);
+         ASSERT(!ctx->Texture._EnabledCoordUnits);
         if (ctx->Light.ShadeModel==GL_SMOOTH) {
            /* smooth shaded, no texturing, stippled or some raster ops */
             if (rgbmode) {
@@ -1206,10 +1146,10 @@ _swrast_choose_triangle( GLcontext *ctx )
       }
    }
    else if (ctx->RenderMode==GL_FEEDBACK) {
-      USE(_mesa_feedback_triangle);
+      USE(_swrast_feedback_triangle);
    }
    else {
       /* GL_SELECT mode */
-      USE(_mesa_select_triangle);
+      USE(_swrast_select_triangle);
    }
 }