diff options
Diffstat (limited to 'src/mesa/main/texobj.c')
-rw-r--r-- | src/mesa/main/texobj.c | 148 |
1 files changed, 84 insertions, 64 deletions
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 13267609614..5bc5639dbf7 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -181,12 +181,11 @@ finish_texture_init(struct gl_context *ctx, GLenum target, * \param texObj the texture object to delete. */ void -_mesa_delete_texture_object( struct gl_context *ctx, struct gl_texture_object *texObj ) +_mesa_delete_texture_object(struct gl_context *ctx, + struct gl_texture_object *texObj) { GLuint i, face; - (void) ctx; - /* Set Target to an invalid value. With some assertions elsewhere * we can try to detect possible use of deleted textures. */ @@ -197,9 +196,9 @@ _mesa_delete_texture_object( struct gl_context *ctx, struct gl_texture_object *t /* free the texture images */ for (face = 0; face < 6; face++) { for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { - if (texObj->Image[face][i]) { - _mesa_delete_texture_image( ctx, texObj->Image[face][i] ); - } + if (texObj->Image[face][i]) { + _mesa_delete_texture_image( ctx, texObj->Image[face][i] ); + } } } @@ -212,7 +211,6 @@ _mesa_delete_texture_object( struct gl_context *ctx, struct gl_texture_object *t - /** * Copy texture object state from one texture object to another. * Use for glPush/PopAttrib. @@ -257,7 +255,7 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, /** - * Clear all texture images of the given texture object. + * Free all texture images of the given texture object. * * \param ctx GL context. * \param t texture object. @@ -265,7 +263,8 @@ _mesa_copy_texture_object( struct gl_texture_object *dest, * \sa _mesa_clear_texture_image(). */ void -_mesa_clear_texture_object(struct gl_context *ctx, struct gl_texture_object *texObj) +_mesa_clear_texture_object(struct gl_context *ctx, + struct gl_texture_object *texObj) { GLuint i, j; @@ -373,15 +372,12 @@ _mesa_reference_texobj(struct gl_texture_object **ptr, /** - * Report why a texture object is incomplete. - * - * \param t texture object. - * \param why string describing why it's incomplete. - * - * \note For debug purposes only. + * Mark a texture object as incomplete. + * \param t texture object + * \param fmt... string describing why it's incomplete (for debugging). */ static void -incomplete(const struct gl_texture_object *t, const char *fmt, ...) +incomplete(struct gl_texture_object *t, const char *fmt, ...) { #if 0 va_list args; @@ -393,6 +389,7 @@ incomplete(const struct gl_texture_object *t, const char *fmt, ...) printf("Texture Obj %d incomplete because: %s\n", t->Name, s); #endif + t->_Complete = GL_FALSE; } @@ -422,14 +419,12 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, */ if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) { incomplete(t, "base level = %d is invalid", baseLevel); - t->_Complete = GL_FALSE; return; } /* Always need the base level image */ if (!t->Image[0][baseLevel]) { incomplete(t, "Image[baseLevel=%d] == NULL", baseLevel); - t->_Complete = GL_FALSE; return; } @@ -438,7 +433,6 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, t->Image[0][baseLevel]->Height == 0 || t->Image[0][baseLevel]->Depth == 0) { incomplete(t, "texture width = 0"); - t->_Complete = GL_FALSE; return; } @@ -449,7 +443,7 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, maxLevels = ctx->Const.MaxTextureLevels; } else if ((t->Target == GL_TEXTURE_2D) || - (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) { + (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) { maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2, t->Image[0][baseLevel]->HeightLog2); maxLevels = ctx->Const.MaxTextureLevels; @@ -489,13 +483,12 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, const GLuint h = t->Image[0][baseLevel]->Height2; GLuint face; for (face = 1; face < 6; face++) { - if (t->Image[face][baseLevel] == NULL || - t->Image[face][baseLevel]->Width2 != w || - t->Image[face][baseLevel]->Height2 != h) { - t->_Complete = GL_FALSE; - incomplete(t, "Cube face missing or mismatched size"); - return; - } + if (t->Image[face][baseLevel] == NULL || + t->Image[face][baseLevel]->Width2 != w || + t->Image[face][baseLevel]->Height2 != h) { + incomplete(t, "Cube face missing or mismatched size"); + return; + } } } @@ -509,7 +502,6 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, GLint maxLevel = t->_MaxLevel; if (minLevel > maxLevel) { - t->_Complete = GL_FALSE; incomplete(t, "minLevel > maxLevel"); return; } @@ -518,12 +510,10 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, for (i = minLevel; i <= maxLevel; i++) { if (t->Image[0][i]) { if (t->Image[0][i]->TexFormat != t->Image[0][baseLevel]->TexFormat) { - t->_Complete = GL_FALSE; incomplete(t, "Format[i] != Format[baseLevel]"); return; } if (t->Image[0][i]->Border != t->Image[0][baseLevel]->Border) { - t->_Complete = GL_FALSE; incomplete(t, "Border[i] != Border[baseLevel]"); return; } @@ -541,12 +531,10 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, } if (i >= minLevel && i <= maxLevel) { if (!t->Image[0][i]) { - t->_Complete = GL_FALSE; incomplete(t, "1D Image[0][i] == NULL"); return; } if (t->Image[0][i]->Width2 != width ) { - t->_Complete = GL_FALSE; incomplete(t, "1D Image[0][i] bad width"); return; } @@ -570,17 +558,14 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, } if (i >= minLevel && i <= maxLevel) { if (!t->Image[0][i]) { - t->_Complete = GL_FALSE; incomplete(t, "2D Image[0][i] == NULL"); return; } if (t->Image[0][i]->Width2 != width) { - t->_Complete = GL_FALSE; incomplete(t, "2D Image[0][i] bad width"); return; } if (t->Image[0][i]->Height2 != height) { - t->_Complete = GL_FALSE; incomplete(t, "2D Image[0][i] bad height"); return; } @@ -595,7 +580,7 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, GLuint width = t->Image[0][baseLevel]->Width2; GLuint height = t->Image[0][baseLevel]->Height2; GLuint depth = t->Image[0][baseLevel]->Depth2; - for (i = baseLevel + 1; i < maxLevels; i++) { + for (i = baseLevel + 1; i < maxLevels; i++) { if (width > 1) { width /= 2; } @@ -608,26 +593,21 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, if (i >= minLevel && i <= maxLevel) { if (!t->Image[0][i]) { incomplete(t, "3D Image[0][i] == NULL"); - t->_Complete = GL_FALSE; return; } if (t->Image[0][i]->_BaseFormat == GL_DEPTH_COMPONENT) { - t->_Complete = GL_FALSE; incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex"); return; } if (t->Image[0][i]->Width2 != width) { - t->_Complete = GL_FALSE; incomplete(t, "3D Image[0][i] bad width"); return; } if (t->Image[0][i]->Height2 != height) { - t->_Complete = GL_FALSE; incomplete(t, "3D Image[0][i] bad height"); return; } if (t->Image[0][i]->Depth2 != depth) { - t->_Complete = GL_FALSE; incomplete(t, "3D Image[0][i] bad depth"); return; } @@ -641,7 +621,7 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, /* make sure 6 cube faces are consistant */ GLuint width = t->Image[0][baseLevel]->Width2; GLuint height = t->Image[0][baseLevel]->Height2; - for (i = baseLevel + 1; i < maxLevels; i++) { + for (i = baseLevel + 1; i < maxLevels; i++) { if (width > 1) { width /= 2; } @@ -653,20 +633,17 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, for (face = 0; face < 6; face++) { /* check that we have images defined */ if (!t->Image[face][i]) { - t->_Complete = GL_FALSE; incomplete(t, "CubeMap Image[n][i] == NULL"); return; } /* Don't support GL_DEPTH_COMPONENT for cube maps */ if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) { - t->_Complete = GL_FALSE; incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex"); return; } /* check that all six images have same size */ - if (t->Image[face][i]->Width2!=width || - t->Image[face][i]->Height2!=height) { - t->_Complete = GL_FALSE; + if (t->Image[face][i]->Width2 != width || + t->Image[face][i]->Height2 != height) { incomplete(t, "CubeMap Image[n][i] bad size"); return; } @@ -689,6 +666,44 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, /** + * Check if the given cube map texture is "cube complete" as defined in + * the OpenGL specification. + */ +GLboolean +_mesa_cube_complete(const struct gl_texture_object *texObj) +{ + const GLint baseLevel = texObj->BaseLevel; + const struct gl_texture_image *img0, *img; + GLuint face; + + if (texObj->Target != GL_TEXTURE_CUBE_MAP) + return GL_FALSE; + + if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) + return GL_FALSE; + + /* check first face */ + img0 = texObj->Image[0][baseLevel]; + if (!img0 || + img0->Width < 1 || + img0->Width != img0->Height) + return GL_FALSE; + + /* check remaining faces vs. first face */ + for (face = 1; face < 6; face++) { + img = texObj->Image[face][baseLevel]; + if (!img || + img->Width != img0->Width || + img->Height != img0->Height || + img->TexFormat != img0->TexFormat) + return GL_FALSE; + } + + return GL_TRUE; +} + + +/** * Mark a texture object dirty. It forces the object to be incomplete * and optionally forces the context to re-validate its state. * @@ -720,6 +735,7 @@ _mesa_get_fallback_texture(struct gl_context *ctx) static GLubyte texels[8 * 8][4]; struct gl_texture_object *texObj; struct gl_texture_image *texImage; + gl_format texFormat; GLuint i; for (i = 0; i < 8 * 8; i++) { @@ -738,12 +754,13 @@ _mesa_get_fallback_texture(struct gl_context *ctx) /* 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, GL_TEXTURE_2D, texImage, - 8, 8, 1, 0, GL_RGBA); + 8, 8, 1, 0, GL_RGBA, texFormat); - texImage->TexFormat = - ctx->Driver.ChooseTextureFormat(ctx, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE); ASSERT(texImage->TexFormat != MESA_FORMAT_NONE); /* set image data */ @@ -831,7 +848,8 @@ _mesa_GenTextures( GLsizei n, GLuint *textures ) * read framebuffer. If so, Unbind it. */ static void -unbind_texobj_from_fbo(struct gl_context *ctx, struct gl_texture_object *texObj) +unbind_texobj_from_fbo(struct gl_context *ctx, + struct gl_texture_object *texObj) { const GLuint n = (ctx->DrawBuffer == ctx->ReadBuffer) ? 1 : 2; GLuint i; @@ -856,7 +874,8 @@ unbind_texobj_from_fbo(struct gl_context *ctx, struct gl_texture_object *texObj) * unbind it if so (revert to default textures). */ static void -unbind_texobj_from_texunits(struct gl_context *ctx, struct gl_texture_object *texObj) +unbind_texobj_from_texunits(struct gl_context *ctx, + struct gl_texture_object *texObj) { GLuint u, tex; @@ -904,7 +923,7 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) = _mesa_lookup_texture(ctx, textures[i]); if (delObj) { - _mesa_lock_texture(ctx, delObj); + _mesa_lock_texture(ctx, delObj); /* Check if texture is bound to any framebuffer objects. * If so, unbind. @@ -917,7 +936,7 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) */ unbind_texobj_from_texunits(ctx, delObj); - _mesa_unlock_texture(ctx, delObj); + _mesa_unlock_texture(ctx, delObj); ctx->NewState |= _NEW_TEXTURE; @@ -1029,7 +1048,7 @@ _mesa_BindTexture( GLenum target, GLuint texName ) } else { /* if this is a new texture id, allocate a texture object now */ - newTexObj = (*ctx->Driver.NewTextureObject)(ctx, texName, target); + newTexObj = (*ctx->Driver.NewTextureObject)(ctx, texName, target); if (!newTexObj) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture"); return; @@ -1112,6 +1131,8 @@ _mesa_PrioritizeTextures( GLsizei n, const GLuint *texName, ctx->NewState |= _NEW_TEXTURE; } + + /** * See if textures are loaded in texture memory. * @@ -1157,23 +1178,24 @@ _mesa_AreTexturesResident(GLsizei n, const GLuint *texName, if (!ctx->Driver.IsTextureResident || ctx->Driver.IsTextureResident(ctx, t)) { /* The texture is resident */ - if (!allResident) - residences[i] = GL_TRUE; + if (!allResident) + residences[i] = GL_TRUE; } else { /* The texture is not resident */ if (allResident) { - allResident = GL_FALSE; - for (j = 0; j < i; j++) - residences[j] = GL_TRUE; - } - residences[i] = GL_FALSE; + allResident = GL_FALSE; + for (j = 0; j < i; j++) + residences[j] = GL_TRUE; + } + residences[i] = GL_FALSE; } } return allResident; } + /** * See if a name corresponds to a texture. * @@ -1234,5 +1256,3 @@ _mesa_unlock_context_textures( struct gl_context *ctx ) } /*@}*/ - - |