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.c169
1 files changed, 97 insertions, 72 deletions
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 3cfbfa5eb54..df64002f994 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -42,10 +42,6 @@
#include "mtypes.h"
-#ifdef __VMS
-#define _mesa_sprintf sprintf
-#endif
-
/**********************************************************************/
/** \name Internal functions */
/*@{*/
@@ -104,11 +100,12 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj,
target == GL_TEXTURE_2D ||
target == GL_TEXTURE_3D ||
target == GL_TEXTURE_CUBE_MAP_ARB ||
- target == GL_TEXTURE_RECTANGLE_NV);
+ target == GL_TEXTURE_RECTANGLE_NV ||
+ target == GL_TEXTURE_1D_ARRAY_EXT ||
+ target == GL_TEXTURE_2D_ARRAY_EXT);
_mesa_bzero(obj, sizeof(*obj));
/* init the non-zero fields */
- _glthread_INIT_MUTEX(obj->Mutex);
obj->RefCount = 1;
obj->Name = name;
obj->Target = target;
@@ -138,13 +135,13 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj,
obj->CompareFunc = GL_LEQUAL; /* ARB_shadow */
obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */
obj->ShadowAmbient = 0.0F; /* ARB/SGIX_shadow_ambient */
- _mesa_init_colortable(&obj->Palette);
}
/**
* Deallocate a texture object struct. It should have already been
* removed from the texture object pool.
+ * Called via ctx->Driver.DeleteTexture() if not overriden by a driver.
*
* \param shared the shared GL state to which the object belongs.
* \param texOjb the texture object to delete.
@@ -167,9 +164,6 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
}
}
- /* destroy the mutex -- it may have allocated memory (eg on bsd) */
- _glthread_DESTROY_MUTEX(texObj->Mutex);
-
/* free this object */
_mesa_free(texObj);
}
@@ -215,7 +209,7 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
dest->_MaxLambda = src->_MaxLambda;
dest->GenerateMipmap = src->GenerateMipmap;
dest->Palette = src->Palette;
- dest->Complete = src->Complete;
+ dest->_Complete = src->_Complete;
}
@@ -257,7 +251,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
const GLint baseLevel = t->BaseLevel;
GLint maxLog2 = 0, maxLevels = 0;
- t->Complete = GL_TRUE; /* be optimistic */
+ t->_Complete = GL_TRUE; /* be optimistic */
/* Always need the base level image */
if (!t->Image[0][baseLevel]) {
@@ -265,7 +259,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
_mesa_sprintf(s, "obj %p (%d) Image[baseLevel=%d] == NULL",
(void *) t, t->Name, baseLevel);
incomplete(t, s);
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
return;
}
@@ -274,16 +268,18 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
t->Image[0][baseLevel]->Height == 0 ||
t->Image[0][baseLevel]->Depth == 0) {
incomplete(t, "texture width = 0");
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
return;
}
/* Compute _MaxLevel */
- if (t->Target == GL_TEXTURE_1D) {
+ if ((t->Target == GL_TEXTURE_1D) ||
+ (t->Target == GL_TEXTURE_1D_ARRAY_EXT)) {
maxLog2 = t->Image[0][baseLevel]->WidthLog2;
maxLevels = ctx->Const.MaxTextureLevels;
}
- else if (t->Target == GL_TEXTURE_2D) {
+ else if ((t->Target == GL_TEXTURE_2D) ||
+ (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) {
maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,
t->Image[0][baseLevel]->HeightLog2);
maxLevels = ctx->Const.MaxTextureLevels;
@@ -326,7 +322,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
if (t->Image[face][baseLevel] == NULL ||
t->Image[face][baseLevel]->Width2 != w ||
t->Image[face][baseLevel]->Height2 != h) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "Non-quare cubemap image");
return;
}
@@ -343,7 +339,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
GLint maxLevel = t->_MaxLevel;
if (minLevel > maxLevel) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "minLevel > maxLevel");
return;
}
@@ -352,12 +348,12 @@ _mesa_test_texobj_completeness( const GLcontext *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;
+ 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;
+ t->_Complete = GL_FALSE;
incomplete(t, "Border[i] != Border[baseLevel]");
return;
}
@@ -365,7 +361,8 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
/* Test things which depend on number of texture image dimensions */
- if (t->Target == GL_TEXTURE_1D) {
+ if ((t->Target == GL_TEXTURE_1D) ||
+ (t->Target == GL_TEXTURE_1D_ARRAY_EXT)) {
/* Test 1-D mipmaps */
GLuint width = t->Image[0][baseLevel]->Width2;
for (i = baseLevel + 1; i < maxLevels; i++) {
@@ -374,12 +371,12 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
if (i >= minLevel && i <= maxLevel) {
if (!t->Image[0][i]) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "1D Image[0][i] == NULL");
return;
}
if (t->Image[0][i]->Width2 != width ) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "1D Image[0][i] bad width");
return;
}
@@ -389,7 +386,8 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
}
}
- else if (t->Target == GL_TEXTURE_2D) {
+ else if ((t->Target == GL_TEXTURE_2D) ||
+ (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) {
/* Test 2-D mipmaps */
GLuint width = t->Image[0][baseLevel]->Width2;
GLuint height = t->Image[0][baseLevel]->Height2;
@@ -402,17 +400,17 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
if (i >= minLevel && i <= maxLevel) {
if (!t->Image[0][i]) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "2D Image[0][i] == NULL");
return;
}
if (t->Image[0][i]->Width2 != width) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "2D Image[0][i] bad width");
return;
}
if (t->Image[0][i]->Height2 != height) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "2D Image[0][i] bad height");
return;
}
@@ -440,26 +438,26 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
if (i >= minLevel && i <= maxLevel) {
if (!t->Image[0][i]) {
incomplete(t, "3D Image[0][i] == NULL");
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
return;
}
if (t->Image[0][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
- t->Complete = GL_FALSE;
+ 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;
+ t->_Complete = GL_FALSE;
incomplete(t, "3D Image[0][i] bad width");
return;
}
if (t->Image[0][i]->Height2 != height) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "3D Image[0][i] bad height");
return;
}
if (t->Image[0][i]->Depth2 != depth) {
- t->Complete = GL_FALSE;
+ t->_Complete = GL_FALSE;
incomplete(t, "3D Image[0][i] bad depth");
return;
}
@@ -485,20 +483,20 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
for (face = 0; face < 6; face++) {
/* check that we have images defined */
if (!t->Image[face][i]) {
- t->Complete = GL_FALSE;
+ 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;
+ 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;
+ t->_Complete = GL_FALSE;
incomplete(t, "CubeMap Image[n][i] bad size");
return;
}
@@ -526,13 +524,6 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
/** \name API functions */
/*@{*/
-/**
- * Texture name generation lock.
- *
- * Used by _mesa_GenTextures() to guarantee that the generation and allocation
- * of texture IDs is atomic.
- */
-_glthread_DECLARE_STATIC_MUTEX(GenTexturesLock);
/**
* Generate texture names.
@@ -542,9 +533,9 @@ _glthread_DECLARE_STATIC_MUTEX(GenTexturesLock);
*
* \sa glGenTextures().
*
- * While holding the GenTexturesLock lock, calls _mesa_HashFindFreeKeyBlock()
- * to find a block of free texture IDs which are stored in \p textures.
- * Corresponding empty texture objects are also generated.
+ * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture
+ * IDs which are stored in \p textures. Corresponding empty texture
+ * objects are also generated.
*/
void GLAPIENTRY
_mesa_GenTextures( GLsizei n, GLuint *textures )
@@ -565,7 +556,7 @@ _mesa_GenTextures( GLsizei n, GLuint *textures )
/*
* This must be atomic (generation and allocation of texture IDs)
*/
- _glthread_LOCK_MUTEX(GenTexturesLock);
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);
@@ -576,20 +567,18 @@ _mesa_GenTextures( GLsizei n, GLuint *textures )
GLenum target = 0;
texObj = (*ctx->Driver.NewTextureObject)( ctx, name, target);
if (!texObj) {
- _glthread_UNLOCK_MUTEX(GenTexturesLock);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
return;
}
/* insert into hash table */
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
_mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
textures[i] = name;
}
- _glthread_UNLOCK_MUTEX(GenTexturesLock);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
}
@@ -630,40 +619,42 @@ unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
+ struct gl_texture_object **curr = NULL;
+
if (texObj == unit->Current1D) {
+ curr = &unit->Current1D;
unit->Current1D = ctx->Shared->Default1D;
- ctx->Shared->Default1D->RefCount++;
- texObj->RefCount--;
- if (texObj == unit->_Current)
- unit->_Current = unit->Current1D;
}
else if (texObj == unit->Current2D) {
+ curr = &unit->Current2D;
unit->Current2D = ctx->Shared->Default2D;
- ctx->Shared->Default2D->RefCount++;
- texObj->RefCount--;
- if (texObj == unit->_Current)
- unit->_Current = unit->Current2D;
}
else if (texObj == unit->Current3D) {
+ curr = &unit->Current3D;
unit->Current3D = ctx->Shared->Default3D;
- ctx->Shared->Default3D->RefCount++;
- texObj->RefCount--;
- if (texObj == unit->_Current)
- unit->_Current = unit->Current3D;
}
else if (texObj == unit->CurrentCubeMap) {
+ curr = &unit->CurrentCubeMap;
unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
- ctx->Shared->DefaultCubeMap->RefCount++;
- texObj->RefCount--;
- if (texObj == unit->_Current)
- unit->_Current = unit->CurrentCubeMap;
}
else if (texObj == unit->CurrentRect) {
+ curr = &unit->CurrentRect;
unit->CurrentRect = ctx->Shared->DefaultRect;
- ctx->Shared->DefaultRect->RefCount++;
+ }
+ else if (texObj == unit->Current1DArray) {
+ curr = &unit->Current1DArray;
+ unit->CurrentRect = ctx->Shared->Default1DArray;
+ }
+ else if (texObj == unit->Current2DArray) {
+ curr = &unit->Current1DArray;
+ unit->CurrentRect = ctx->Shared->Default2DArray;
+ }
+
+ if (curr) {
+ (*curr)->RefCount++;
texObj->RefCount--;
if (texObj == unit->_Current)
- unit->_Current = unit->CurrentRect;
+ unit->_Current = *curr;
}
}
}
@@ -802,6 +793,20 @@ _mesa_BindTexture( GLenum target, GLuint texName )
}
oldTexObj = texUnit->CurrentRect;
break;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ if (!ctx->Extensions.MESA_texture_array) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
+ return;
+ }
+ oldTexObj = texUnit->Current1DArray;
+ break;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ if (!ctx->Extensions.MESA_texture_array) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
+ return;
+ }
+ oldTexObj = texUnit->Current2DArray;
+ break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
return;
@@ -838,6 +843,12 @@ _mesa_BindTexture( GLenum target, GLuint texName )
case GL_TEXTURE_RECTANGLE_NV:
newTexObj = ctx->Shared->DefaultRect;
break;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ newTexObj = ctx->Shared->Default1DArray;
+ break;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ newTexObj = ctx->Shared->Default2DArray;
+ break;
default:
; /* Bad targets are caught above */
}
@@ -908,6 +919,12 @@ _mesa_BindTexture( GLenum target, GLuint texName )
case GL_TEXTURE_RECTANGLE_NV:
texUnit->CurrentRect = newTexObj;
break;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ texUnit->Current1DArray = newTexObj;
+ break;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ texUnit->Current2DArray = newTexObj;
+ break;
default:
_mesa_problem(ctx, "bad target in BindTexture");
return;
@@ -1063,14 +1080,21 @@ _mesa_IsTexture( GLuint texture )
return t && t->Target;
}
-/* Simplest implementation of texture locking: Grab the a new mutex in
+
+/**
+ * Simplest implementation of texture locking: Grab the a new mutex in
* the shared context. Examine the shared context state timestamp and
* if there has been a change, set the appropriate bits in
* ctx->NewState.
*
- * See also _mesa_lock/unlock_texture in texobj.h
+ * This is used to deal with synchronizing things when a texture object
+ * is used/modified by different contexts (or threads) which are sharing
+ * the texture.
+ *
+ * See also _mesa_lock/unlock_texture() in teximage.h
*/
-void _mesa_lock_context_textures( GLcontext *ctx )
+void
+_mesa_lock_context_textures( GLcontext *ctx )
{
_glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
@@ -1081,7 +1105,8 @@ void _mesa_lock_context_textures( GLcontext *ctx )
}
-void _mesa_unlock_context_textures( GLcontext *ctx )
+void
+_mesa_unlock_context_textures( GLcontext *ctx )
{
assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp);
_glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);