[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