summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/texobj.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/texobj.c')
-rw-r--r--src/mesa/main/texobj.c148
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 )
}
/*@}*/
-
-