Previously, this function only handled 2D textures.

The fallback texture is used when we try to sample from an incomplete
texture object.  GLSL says sampling an incomplete texture should return
(0,0,0,1).
---
 src/mesa/main/mtypes.h   |    2 +-
 src/mesa/main/shared.c   |    8 ++-
 src/mesa/main/texobj.c   |  115 ++++++++++++++++++++++++++++++++++++----------
 src/mesa/main/texobj.h   |    4 +-
 src/mesa/main/texstate.c |   10 +++-
 5 files changed, 107 insertions(+), 32 deletions(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 107371e..5158100 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2419,7 +2419,7 @@ struct gl_shared_state
    struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS];
 
    /** Fallback texture used when a bound texture is incomplete */
-   struct gl_texture_object *FallbackTex;
+   struct gl_texture_object *FallbackTex[NUM_TEXTURE_TARGETS];
 
    /**
     * \name Thread safety and statechange notification for texture
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index 276fac1..f889abe 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -307,9 +307,11 @@ free_shared_state(struct gl_context *ctx, struct 
gl_shared_state *shared)
 {
    GLuint i;
 
-   /* Free the dummy/fallback texture object */
-   if (shared->FallbackTex)
-      ctx->Driver.DeleteTexture(ctx, shared->FallbackTex);
+   /* Free the dummy/fallback texture objects */
+   for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
+      if (shared->FallbackTex[i])
+         ctx->Driver.DeleteTexture(ctx, shared->FallbackTex[i]);
+   }
 
    /*
     * Free display lists
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 7ee2005..112d58a 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -757,59 +757,126 @@ _mesa_dirty_texobj(struct gl_context *ctx, struct 
gl_texture_object *texObj,
 
 
 /**
- * Return pointer to a default/fallback texture.
- * The texture is a 2D 8x8 RGBA texture with all texels = (0,0,0,1).
- * That's the value a sampler should get when sampling from an
+ * Return pointer to a default/fallback texture of the given type/target.
+ * The texture is an RGBA texture with all texels = (0,0,0,1).
+ * That's the value a GLSL sampler should get when sampling from an
  * incomplete texture.
  */
 struct gl_texture_object *
-_mesa_get_fallback_texture(struct gl_context *ctx)
+_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
 {
-   if (!ctx->Shared->FallbackTex) {
+   if (!ctx->Shared->FallbackTex[tex]) {
       /* create fallback texture now */
-      static GLubyte texels[8 * 8][4];
+      const GLsizei width = 4, height = 4, depth = 4;
+      GLubyte texels[width * height * depth][4];
       struct gl_texture_object *texObj;
       struct gl_texture_image *texImage;
       gl_format texFormat;
-      GLuint i;
+      GLuint i, dims, face, numFaces = 1;
+      GLenum target;
 
-      for (i = 0; i < 8 * 8; i++) {
+      for (i = 0; i < width * height * depth; i++) {
          texels[i][0] =
          texels[i][1] =
          texels[i][2] = 0x0;
          texels[i][3] = 0xff;
       }
 
+      switch (tex) {
+      case TEXTURE_2D_ARRAY_INDEX:
+         dims = 3;
+         target = GL_TEXTURE_2D_ARRAY;
+         break;
+      case TEXTURE_1D_ARRAY_INDEX:
+         dims = 2;
+         target = GL_TEXTURE_1D_ARRAY;
+         break;
+      case TEXTURE_CUBE_INDEX:
+         dims = 2;
+         target = GL_TEXTURE_CUBE_MAP;
+         numFaces = 6;
+         break;
+      case TEXTURE_3D_INDEX:
+         dims = 3;
+         target = GL_TEXTURE_3D;
+         break;
+      case TEXTURE_RECT_INDEX:
+         dims = 2;
+         target = GL_TEXTURE_RECTANGLE;
+         break;
+      case TEXTURE_2D_INDEX:
+         dims = 2;
+         target = GL_TEXTURE_2D;
+         break;
+      case TEXTURE_1D_INDEX:
+         dims = 1;
+         target = GL_TEXTURE_1D;
+         break;
+      case TEXTURE_BUFFER_INDEX:
+      case TEXTURE_EXTERNAL_INDEX:
+      default:
+         /* no-op */
+         return NULL;
+      }
+
       /* create texture object */
-      texObj = ctx->Driver.NewTextureObject(ctx, 0, GL_TEXTURE_2D);
+      texObj = ctx->Driver.NewTextureObject(ctx, 0, target);
       assert(texObj->RefCount == 1);
       texObj->Sampler.MinFilter = GL_NEAREST;
       texObj->Sampler.MagFilter = GL_NEAREST;
 
-      /* create level[0] texture image */
-      texImage = _mesa_get_tex_image(ctx, texObj, GL_TEXTURE_2D, 0);
-
       texFormat = ctx->Driver.ChooseTextureFormat(ctx, GL_RGBA, GL_RGBA,
                                                   GL_UNSIGNED_BYTE);
 
-      /* init the image fields */
-      _mesa_init_teximage_fields(ctx, texImage,
-                                 8, 8, 1, 0, GL_RGBA, texFormat); 
+      /* need a loop here just for cube maps */
+      for (face = 0; face < numFaces; face++) {
+         GLenum faceTarget;
 
-      ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
-
-      /* set image data */
-      ctx->Driver.TexImage2D(ctx, texImage, GL_RGBA,
-                             8, 8, 0,
-                             GL_RGBA, GL_UNSIGNED_BYTE, texels,
-                             &ctx->DefaultPacking);
+         if (target == GL_TEXTURE_CUBE_MAP)
+            faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
+         else
+            faceTarget = target;
+
+         /* initialize level[0] texture image */
+         texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, 0);
+
+         _mesa_init_teximage_fields(ctx, texImage,
+                                    width,
+                                    (dims > 1) ? height : 1,
+                                    (dims > 2) ? depth : 1,
+                                    0, /* border */
+                                    GL_RGBA, texFormat);
+
+         switch (dims) {
+         case 1:
+            ctx->Driver.TexImage1D(ctx, texImage, GL_RGBA,
+                                   width, 0,
+                                   GL_RGBA, GL_UNSIGNED_BYTE, texels,
+                                   &ctx->DefaultPacking);
+            break;
+         case 2:
+            ctx->Driver.TexImage2D(ctx, texImage, GL_RGBA,
+                                   width, height, 0,
+                                   GL_RGBA, GL_UNSIGNED_BYTE, texels,
+                                   &ctx->DefaultPacking);
+            break;
+         case 3:
+            ctx->Driver.TexImage3D(ctx, texImage, GL_RGBA,
+                                   width, height, depth, 0,
+                                   GL_RGBA, GL_UNSIGNED_BYTE, texels,
+                                   &ctx->DefaultPacking);
+            break;
+         default:
+            _mesa_problem(ctx, "bad dims in _mesa_get_fallback_texture()");
+         }
+      }
 
       _mesa_test_texobj_completeness(ctx, texObj);
       assert(texObj->_Complete);
 
-      ctx->Shared->FallbackTex = texObj;
+      ctx->Shared->FallbackTex[tex] = texObj;
    }
-   return ctx->Shared->FallbackTex;
+   return ctx->Shared->FallbackTex[tex];
 }
 
 
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index 9ca7a4c..03dfbe3 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -34,8 +34,8 @@
 
 #include "compiler.h"
 #include "glheader.h"
+#include "mtypes.h"
 
-struct gl_context;
 
 /**
  * \name Internal functions
@@ -89,7 +89,7 @@ _mesa_dirty_texobj(struct gl_context *ctx, struct 
gl_texture_object *texObj,
                    GLboolean invalidate_state);
 
 extern struct gl_texture_object *
-_mesa_get_fallback_texture(struct gl_context *ctx);
+_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex);
 
 extern void
 _mesa_unlock_context_textures( struct gl_context *ctx );
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 7cd2858..351a556 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -586,9 +586,15 @@ update_texture_state( struct gl_context *ctx )
              * object, but there isn't one (or it's incomplete).  Use the
              * fallback texture.
              */
-            struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx);
-            texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX;
+            struct gl_texture_object *texObj;
+            gl_texture_index texTarget;
+
+            assert(_mesa_bitcount(enabledTargets) == 1);
+
+            texTarget = (gl_texture_index) (_mesa_ffs(enabledTargets) - 1);
+            texObj = _mesa_get_fallback_texture(ctx, texTarget);
             _mesa_reference_texobj(&texUnit->_Current, texObj);
+            texUnit->_ReallyEnabled = 1 << texTarget;
          }
          else {
             /* fixed-function: texture unit is really disabled */
-- 
1.7.3.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to