----- 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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev