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.c160
1 files changed, 92 insertions, 68 deletions
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 18f942fa8e2..f0372237ca2 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -1,4 +1,4 @@
-/* $Id: texobj.c,v 1.33 2000/11/11 20:23:47 brianp Exp $ */
+/* $Id: texobj.c,v 1.34 2000/11/19 23:10:25 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -50,11 +50,12 @@
* Input: shared - the shared GL state structure to contain the texture object
* name - integer name for the texture object
* dimensions - either 1, 2, 3 or 6 (cube map)
+ * zero is ok for the sake of GenTextures()
* Return: pointer to new texture object
*/
struct gl_texture_object *
-gl_alloc_texture_object( struct gl_shared_state *shared, GLuint name,
- GLuint dimensions)
+_mesa_alloc_texture_object( struct gl_shared_state *shared, GLuint name,
+ GLuint dimensions)
{
struct gl_texture_object *obj;
@@ -103,19 +104,13 @@ gl_alloc_texture_object( struct gl_shared_state *shared, GLuint name,
* Input: shared - the shared GL state to which the object belongs
* t - the texture object to delete
*/
-void gl_free_texture_object( struct gl_shared_state *shared,
- struct gl_texture_object *t )
+void _mesa_free_texture_object( struct gl_shared_state *shared,
+ struct gl_texture_object *t )
{
struct gl_texture_object *tprev, *tcurr;
assert(t);
- /* Remove t from dirty list so we don't touch free'd memory later.
- * Test for shared since Proxy texture aren't in global linked list.
- */
- if (shared)
- gl_remove_texobj_from_dirty_list( shared, t );
-
/* unlink t from the linked list */
if (shared) {
_glthread_LOCK_MUTEX(shared->Mutex);
@@ -144,7 +139,7 @@ void gl_free_texture_object( struct gl_shared_state *shared,
_mesa_free_colortable_data(&t->Palette);
- /* free texture images */
+ /* free the texture images */
{
GLuint i;
for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
@@ -153,10 +148,15 @@ void gl_free_texture_object( struct gl_shared_state *shared,
}
}
}
+
/* free this object */
FREE( t );
}
+
+/*
+ * Report why a texture object is incomplete. (for debug only)
+ */
#if 0
static void
incomplete(const struct gl_texture_object *t, const char *why)
@@ -169,7 +169,7 @@ incomplete(const struct gl_texture_object *t, const char *why)
/*
- * Examine a texture object to determine if it is complete or not.
+ * Examine a texture object to determine if it is complete.
* The t->Complete flag will be set to GL_TRUE or GL_FALSE accordingly.
*/
void
@@ -180,7 +180,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
t->Complete = GL_TRUE; /* be optimistic */
- /* Always need level zero image */
+ /* Always need the base level image */
if (!t->Image[baseLevel]) {
incomplete(t, "Image[baseLevel] == NULL");
t->Complete = GL_FALSE;
@@ -207,7 +207,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
if (t->Dimensions == 6) {
- /* make sure all six level 0 images are same size */
+ /* make sure that all six cube map level 0 images are the same size */
const GLint w = t->Image[baseLevel]->Width2;
const GLint h = t->Image[baseLevel]->Height2;
if (!t->NegX[baseLevel] ||
@@ -444,7 +444,7 @@ _mesa_GenTextures( GLsizei n, GLuint *texName )
for (i=0;i<n;i++) {
GLuint name = first + i;
GLuint dims = 0;
- (void) gl_alloc_texture_object(ctx->Shared, name, dims);
+ (void) _mesa_alloc_texture_object(ctx->Shared, name, dims);
}
_glthread_UNLOCK_MUTEX(GenTexturesLock);
@@ -467,36 +467,42 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *texName)
return;
for (i=0;i<n;i++) {
- struct gl_texture_object *t;
- if (texName[i]>0) {
- t = (struct gl_texture_object *)
+ if (texName[i] > 0) {
+ struct gl_texture_object *delObj = (struct gl_texture_object *)
_mesa_HashLookup(ctx->Shared->TexObjects, texName[i]);
- if (t) {
+ if (delObj) {
/* First check if this texture is currently bound.
* If so, unbind it and decrement the reference count.
*/
GLuint u;
for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
- GLuint d;
- for (d = 1 ; d <= 3 ; d++) {
- if (unit->CurrentD[d] == t) {
- unit->CurrentD[d] = ctx->Shared->DefaultD[d];
- ctx->Shared->DefaultD[d]->RefCount++;
- t->RefCount--;
- ASSERT( t->RefCount >= 0 );
- ctx->NewState |= _NEW_TEXTURE;
- }
- }
+ if (delObj == unit->Current1D) {
+ unit->Current1D = ctx->Shared->Default1D;
+ ctx->Shared->Default1D->RefCount++;
+ }
+ else if (delObj == unit->Current2D) {
+ unit->Current2D = ctx->Shared->Default2D;
+ ctx->Shared->Default2D->RefCount++;
+ }
+ else if (delObj == unit->Current3D) {
+ unit->Current3D = ctx->Shared->Default3D;
+ ctx->Shared->Default3D->RefCount++;
+ }
+ else if (delObj == unit->CurrentCubeMap) {
+ unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
+ ctx->Shared->DefaultCubeMap->RefCount++;
+ }
}
+ ctx->NewState |= _NEW_TEXTURE;
/* Decrement reference count and delete if zero */
- t->RefCount--;
- ASSERT( t->RefCount >= 0 );
- if (t->RefCount == 0) {
+ delObj->RefCount--;
+ ASSERT( delObj->RefCount >= 0 );
+ if (delObj->RefCount == 0) {
if (ctx->Driver.DeleteTexture)
- (*ctx->Driver.DeleteTexture)( ctx, t );
- gl_free_texture_object(ctx->Shared, t);
+ (*ctx->Driver.DeleteTexture)( ctx, delObj );
+ _mesa_free_texture_object(ctx->Shared, delObj);
}
}
}
@@ -516,7 +522,7 @@ _mesa_BindTexture( GLenum target, GLuint texName )
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *oldTexObj;
struct gl_texture_object *newTexObj;
- GLuint dim;
+ GLuint targetDim;
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
fprintf(stderr, "glBindTexture %s %d\n",
@@ -526,20 +532,20 @@ _mesa_BindTexture( GLenum target, GLuint texName )
switch (target) {
case GL_TEXTURE_1D:
- dim = 1;
- oldTexObj = texUnit->CurrentD[1];
+ targetDim = 1;
+ oldTexObj = texUnit->Current1D;
break;
case GL_TEXTURE_2D:
- dim = 2;
- oldTexObj = texUnit->CurrentD[2];
+ targetDim = 2;
+ oldTexObj = texUnit->Current2D;
break;
case GL_TEXTURE_3D:
- dim = 3;
- oldTexObj = texUnit->CurrentD[3];
+ targetDim = 3;
+ oldTexObj = texUnit->Current3D;
break;
case GL_TEXTURE_CUBE_MAP_ARB:
if (ctx->Extensions.ARB_texture_cube_map) {
- dim = 6;
+ targetDim = 6;
oldTexObj = texUnit->CurrentCubeMap;
break;
}
@@ -550,42 +556,65 @@ _mesa_BindTexture( GLenum target, GLuint texName )
}
if (oldTexObj->Name == texName)
- return;
+ return; /* rebinding the same texture- no change */
+ /*
+ * Get pointer to new texture object (newTexObj)
+ */
if (texName == 0) {
- if (target == GL_TEXTURE_CUBE_MAP_ARB)
- newTexObj = ctx->Shared->DefaultCubeMap;
- else
- newTexObj = ctx->Shared->DefaultD[dim];
+ /* newTexObj = a default texture object */
+ switch (target) {
+ case GL_TEXTURE_1D:
+ newTexObj = ctx->Shared->Default1D;
+ break;
+ case GL_TEXTURE_2D:
+ newTexObj = ctx->Shared->Default2D;
+ break;
+ case GL_TEXTURE_3D:
+ newTexObj = ctx->Shared->Default3D;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ newTexObj = ctx->Shared->DefaultCubeMap;
+ break;
+ default:
+ ; /* Bad targets are caught above */
+ }
}
else {
- struct _mesa_HashTable *hash = ctx->Shared->TexObjects;
+ /* non-default texture object */
+ const struct _mesa_HashTable *hash = ctx->Shared->TexObjects;
newTexObj = (struct gl_texture_object *) _mesa_HashLookup(hash, texName);
-
- if (!newTexObj)
- newTexObj = gl_alloc_texture_object(ctx->Shared, texName, dim);
-
- if (newTexObj->Dimensions != dim) {
- if (newTexObj->Dimensions) {
+ if (newTexObj) {
+ /* error checking */
+ if (newTexObj->Dimensions > 0 && newTexObj->Dimensions != targetDim) {
/* the named texture object's dimensions don't match the target */
- gl_error( ctx, GL_INVALID_OPERATION, "glBindTexture" );
- return;
- }
- newTexObj->Dimensions = dim;
+ gl_error( ctx, GL_INVALID_OPERATION, "glBindTexture" );
+ return;
+ }
}
+ else {
+ /* if this is a new texture id, allocate a texture object now */
+ newTexObj = _mesa_alloc_texture_object(ctx->Shared, texName, targetDim);
+ if (!newTexObj) {
+ gl_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
+ return;
+ }
+ }
+ newTexObj->Dimensions = targetDim;
}
newTexObj->RefCount++;
+ /* do the actual binding */
switch (target) {
case GL_TEXTURE_1D:
- texUnit->CurrentD[1] = newTexObj;
+ texUnit->Current1D = newTexObj;
break;
case GL_TEXTURE_2D:
- texUnit->CurrentD[2] = newTexObj;
+ texUnit->Current2D = newTexObj;
break;
case GL_TEXTURE_3D:
- texUnit->CurrentD[3] = newTexObj;
+ texUnit->Current3D = newTexObj;
break;
case GL_TEXTURE_CUBE_MAP_ARB:
texUnit->CurrentCubeMap = newTexObj;
@@ -594,11 +623,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
gl_problem(ctx, "bad target in BindTexture");
}
- /* If we've changed the CurrentD[123] texture object then update the
- * ctx->Texture.Current pointer to point to the new texture object.
- */
- texUnit->_Current = texUnit->CurrentD[texUnit->_CurrentDimension];
-
ctx->NewState |= _NEW_TEXTURE;
/* Pass BindTexture call to device driver */
@@ -612,7 +636,7 @@ _mesa_BindTexture( GLenum target, GLuint texName )
if (ctx->Driver.DeleteTexture) {
(*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
}
- gl_free_texture_object(ctx->Shared, oldTexObj);
+ _mesa_free_texture_object(ctx->Shared, oldTexObj);
}
}
}