Mesa (master): mesa: create/ use a fallback texture when bound texture is incomplete

Brian Paul brianp at kemper.freedesktop.org
Fri May 1 15:35:14 UTC 2009


Module: Mesa
Branch: master
Commit: 3f25219c7bf0f090502489928f0f018e62c4f6cf
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3f25219c7bf0f090502489928f0f018e62c4f6cf

Author: Brian Paul <brianp at vmware.com>
Date:   Fri May  1 09:30:32 2009 -0600

mesa: create/use a fallback texture when bound texture is incomplete

When a GLSL sampler reads from an incomplete texture it should
return (0,0,0,1).  Instead of jumping through hoops in all the drivers
to make this happen, just create/install a fallback texture with those
texel values.

Fixes piglit/fp-incomplete-tex on i965 and more importantly, fixes some
GPU lockups when trying to sample from missing surfaces.  If a binding
table entry is NULL, it seems that sampling sometimes works, but not
always (lockup).

Todo: create a fallback texture for each type of texture target?

---

 src/mesa/main/mtypes.h   |    3 ++
 src/mesa/main/texobj.c   |   53 ++++++++++++++++++++++++++++++++++++++++++++++
 src/mesa/main/texobj.h   |    3 ++
 src/mesa/main/texstate.c |    9 ++++++-
 4 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 30c7cca..38c3b1b 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2050,6 +2050,9 @@ struct gl_shared_state
    /** Default texture objects (shared by all texture units) */
    struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS];
 
+   /** Fallback texture used when a bound texture is incomplete */
+   struct gl_texture_object *FallbackTex;
+
    /**
     * \name Thread safety and statechange notification for texture
     * objects. 
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index b63f747..0024efc 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -662,6 +662,59 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
    }
 }
 
+
+/**
+ * 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
+ * incomplete texture.
+ */
+struct gl_texture_object *
+_mesa_get_fallback_texture(GLcontext *ctx)
+{
+   if (!ctx->Shared->FallbackTex) {
+      /* create fallback texture now */
+      static GLubyte texels[8 * 8][4];
+      struct gl_texture_object *texObj;
+      struct gl_texture_image *texImage;
+      GLuint i;
+
+      for (i = 0; i < 8 * 8; i++) {
+         texels[i][0] =
+         texels[i][1] =
+         texels[i][2] = 0x0;
+         texels[i][3] = 0xff;
+      }
+
+      /* create texture object */
+      texObj = ctx->Driver.NewTextureObject(ctx, 0, GL_TEXTURE_2D);
+      assert(texObj->RefCount == 1);
+      texObj->MinFilter = GL_NEAREST;
+      texObj->MagFilter = GL_NEAREST;
+
+      /* create level[0] texture image */
+      texImage = _mesa_get_tex_image(ctx, texObj, GL_TEXTURE_2D, 0);
+
+      /* init the image fields */
+      _mesa_init_teximage_fields(ctx, GL_TEXTURE_2D, texImage,
+                                    8, 8, 1, 0, GL_RGBA); 
+
+      /* set image data */
+      ctx->Driver.TexImage2D(ctx, GL_TEXTURE_2D, 0, GL_RGBA,
+                             8, 8, 0,
+                             GL_RGBA, GL_UNSIGNED_BYTE, texels,
+                             &ctx->DefaultPacking, texObj, texImage);
+
+      _mesa_test_texobj_completeness(ctx, texObj);
+      assert(texObj->_Complete);
+
+      ctx->Shared->FallbackTex = texObj;
+   }
+   return ctx->Shared->FallbackTex;
+}
+
+
+
 /*@}*/
 
 
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index d5374c5..2599c08 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -65,6 +65,9 @@ extern void
 _mesa_test_texobj_completeness( const GLcontext *ctx,
                                 struct gl_texture_object *obj );
 
+extern struct gl_texture_object *
+_mesa_get_fallback_texture(GLcontext *ctx);
+
 extern void
 _mesa_unlock_context_textures( GLcontext *ctx );
 
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 73f8a53..32d55ba 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -561,8 +561,13 @@ update_texture_state( GLcontext *ctx )
       }
 
       if (!texUnit->_ReallyEnabled) {
-         _mesa_reference_texobj(&texUnit->_Current, NULL);
-         continue;
+         /* If we get here it means the shader (or fixed-function state)
+          * is expecting a texture 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;
+         _mesa_reference_texobj(&texUnit->_Current, texObj);
       }
 
       /* if we get here, we know this texture unit is enabled */




More information about the mesa-commit mailing list