[Mesa-dev] [PATCH 10/13] mesa: fix _mesa_get_fallback_texture() to handle all texture targets

Jose Fonseca jfonseca at vmware.com
Mon Feb 13 08:47:54 PST 2012



----- Original Message -----
> 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   |  118
>  ++++++++++++++++++++++++++++++++++++---------
>  src/mesa/main/texobj.h   |    4 +-
>  src/mesa/main/texstate.c |   10 +++-
>  5 files changed, 110 insertions(+), 32 deletions(-)
> 
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index 5ef97c8..9200f3f 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -2483,7 +2483,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 c07ce82..2269476 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 1b61d3a..93a4cf6 100644
> --- a/src/mesa/main/texobj.c
> +++ b/src/mesa/main/texobj.c
> @@ -759,59 +759,129 @@ _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];

I'm not sure this builds correctly on MSVC. You might need a #define.

Why 8x8 or 4x4, and not 1x1?

Otherwise looks good.

Jose

>        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);
> +      if (!texObj)
> +         return NULL;
> +
>        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);
> -
> -      ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
> +      /* need a loop here just for cube maps */
> +      for (face = 0; face < numFaces; face++) {
> +         GLenum faceTarget;
>  
> -      /* 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 cc49916..187ec9c 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) (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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 


More information about the mesa-dev mailing list