New device driver hooks for texture object and texture image creation to
allow drivers to implement C++-like inheritance via containment. Lots of assorted clean-ups related to texture objects.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $Id: osmesa.c,v 1.101 2003/03/04 19:16:47 brianp Exp $ */
|
||||
/* $Id: osmesa.c,v 1.102 2003/04/01 16:41:57 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "matrix.h"
|
||||
#include "mtypes.h"
|
||||
#include "texformat.h"
|
||||
#include "texobj.h"
|
||||
#include "texstore.h"
|
||||
#include "array_cache/acache.h"
|
||||
#include "swrast/swrast.h"
|
||||
@@ -648,7 +649,7 @@ hook_in_driver_functions( GLcontext *ctx )
|
||||
|
||||
ctx->Driver.Accum = _swrast_Accum;
|
||||
ctx->Driver.Bitmap = _swrast_Bitmap;
|
||||
ctx->Driver.Clear = clear; /* = _swrast_Clear */
|
||||
ctx->Driver.Clear = clear; /* uses _swrast_Clear */
|
||||
ctx->Driver.CopyPixels = _swrast_CopyPixels;
|
||||
ctx->Driver.DrawPixels = _swrast_DrawPixels;
|
||||
ctx->Driver.ReadPixels = _swrast_ReadPixels;
|
||||
@@ -670,6 +671,9 @@ hook_in_driver_functions( GLcontext *ctx )
|
||||
ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
|
||||
ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
|
||||
|
||||
ctx->Driver.NewTextureObject = _mesa_new_texture_object;
|
||||
ctx->Driver.DeleteTexture = _mesa_delete_texture_object;
|
||||
|
||||
ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
|
||||
ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
|
||||
ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* $Id: xm_dd.c,v 1.45 2003/03/27 17:51:33 brianp Exp $ */
|
||||
/* $Id: xm_dd.c,v 1.46 2003/04/01 16:41:58 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -965,6 +965,9 @@ void xmesa_init_pointers( GLcontext *ctx )
|
||||
ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
|
||||
ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
|
||||
|
||||
ctx->Driver.NewTextureObject = _mesa_new_texture_object;
|
||||
ctx->Driver.DeleteTexture = _mesa_delete_texture_object;
|
||||
|
||||
ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
|
||||
ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
|
||||
ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* $Id: context.c,v 1.194 2003/03/01 01:50:20 brianp Exp $ */
|
||||
/* $Id: context.c,v 1.195 2003/04/01 16:41:50 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -637,15 +637,14 @@ free_matrix_stack( struct matrix_stack *stack )
|
||||
/*
|
||||
* Allocate and initialize a shared context state structure.
|
||||
*/
|
||||
static struct gl_shared_state *
|
||||
alloc_shared_state( void )
|
||||
static GLboolean
|
||||
alloc_shared_state( GLcontext *ctx )
|
||||
{
|
||||
struct gl_shared_state *ss;
|
||||
GLboolean outOfMemory;
|
||||
|
||||
ss = CALLOC_STRUCT(gl_shared_state);
|
||||
struct gl_shared_state *ss = CALLOC_STRUCT(gl_shared_state);
|
||||
if (!ss)
|
||||
return NULL;
|
||||
return GL_FALSE;
|
||||
|
||||
ctx->Shared = ss;
|
||||
|
||||
_glthread_INIT_MUTEX(ss->Mutex);
|
||||
|
||||
@@ -655,64 +654,66 @@ alloc_shared_state( void )
|
||||
ss->Programs = _mesa_NewHashTable();
|
||||
#endif
|
||||
|
||||
/* Default Texture objects */
|
||||
outOfMemory = GL_FALSE;
|
||||
ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
|
||||
if (!ss->Default1D)
|
||||
goto cleanup;
|
||||
|
||||
ss->Default1D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_1D);
|
||||
if (!ss->Default1D) {
|
||||
outOfMemory = GL_TRUE;
|
||||
}
|
||||
ss->Default2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
|
||||
if (!ss->Default2D)
|
||||
goto cleanup;
|
||||
|
||||
ss->Default2D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_2D);
|
||||
if (!ss->Default2D) {
|
||||
outOfMemory = GL_TRUE;
|
||||
}
|
||||
ss->Default3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
|
||||
if (!ss->Default3D)
|
||||
goto cleanup;
|
||||
|
||||
ss->Default3D = _mesa_alloc_texture_object(ss, 0, GL_TEXTURE_3D);
|
||||
if (!ss->Default3D) {
|
||||
outOfMemory = GL_TRUE;
|
||||
}
|
||||
ss->DefaultCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
|
||||
if (!ss->DefaultCubeMap)
|
||||
goto cleanup;
|
||||
|
||||
ss->DefaultCubeMap = _mesa_alloc_texture_object(ss, 0,
|
||||
GL_TEXTURE_CUBE_MAP_ARB);
|
||||
if (!ss->DefaultCubeMap) {
|
||||
outOfMemory = GL_TRUE;
|
||||
}
|
||||
ss->DefaultRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
|
||||
if (!ss->DefaultRect)
|
||||
goto cleanup;
|
||||
|
||||
ss->DefaultRect = _mesa_alloc_texture_object(ss, 0,
|
||||
GL_TEXTURE_RECTANGLE_NV);
|
||||
if (!ss->DefaultRect) {
|
||||
outOfMemory = GL_TRUE;
|
||||
}
|
||||
|
||||
if (!ss->DisplayList || !ss->TexObjects
|
||||
#if FEATURE_NV_vertex_program
|
||||
|| !ss->Programs
|
||||
#if 0
|
||||
_mesa_save_texture_object(ctx, ss->Default1D);
|
||||
_mesa_save_texture_object(ctx, ss->Default2D);
|
||||
_mesa_save_texture_object(ctx, ss->Default3D);
|
||||
_mesa_save_texture_object(ctx, ss->DefaultCubeMap);
|
||||
_mesa_save_texture_object(ctx, ss->DefaultRect);
|
||||
#endif
|
||||
|| outOfMemory) {
|
||||
|
||||
/* Effectively bind the default textures to all texture units */
|
||||
ss->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
|
||||
ss->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
|
||||
ss->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
|
||||
ss->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
|
||||
ss->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
|
||||
|
||||
return GL_TRUE;
|
||||
|
||||
cleanup:
|
||||
/* Ran out of memory at some point. Free everything and return NULL */
|
||||
if (ss->DisplayList)
|
||||
_mesa_DeleteHashTable(ss->DisplayList);
|
||||
if (ss->TexObjects)
|
||||
_mesa_DeleteHashTable(ss->TexObjects);
|
||||
#if FEATURE_NV_vertex_program
|
||||
if (ss->Programs)
|
||||
_mesa_DeleteHashTable(ss->Programs);
|
||||
#endif
|
||||
if (ss->Default1D)
|
||||
_mesa_free_texture_object(ss, ss->Default1D);
|
||||
(*ctx->Driver.DeleteTexture)(ctx, ss->Default1D);
|
||||
if (ss->Default2D)
|
||||
_mesa_free_texture_object(ss, ss->Default2D);
|
||||
(*ctx->Driver.DeleteTexture)(ctx, ss->Default2D);
|
||||
if (ss->Default3D)
|
||||
_mesa_free_texture_object(ss, ss->Default3D);
|
||||
(*ctx->Driver.DeleteTexture)(ctx, ss->Default3D);
|
||||
if (ss->DefaultCubeMap)
|
||||
_mesa_free_texture_object(ss, ss->DefaultCubeMap);
|
||||
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
|
||||
if (ss->DefaultRect)
|
||||
_mesa_free_texture_object(ss, ss->DefaultRect);
|
||||
FREE(ss);
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
return ss;
|
||||
}
|
||||
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
|
||||
if (ss)
|
||||
_mesa_free(ss);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -735,11 +736,19 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
|
||||
_mesa_DeleteHashTable(ss->DisplayList);
|
||||
|
||||
/* Free texture objects */
|
||||
while (ss->TexObjectList) {
|
||||
if (ctx->Driver.DeleteTexture)
|
||||
(*ctx->Driver.DeleteTexture)( ctx, ss->TexObjectList );
|
||||
/* this function removes from linked list too! */
|
||||
_mesa_free_texture_object(ss, ss->TexObjectList);
|
||||
ASSERT(ctx->Driver.DeleteTexture);
|
||||
while (1) {
|
||||
GLuint texName = _mesa_HashFirstEntry(ss->TexObjects);
|
||||
if (texName) {
|
||||
struct gl_texture_object *texObj = (struct gl_texture_object *)
|
||||
_mesa_HashLookup(ss->TexObjects, texName);
|
||||
ASSERT(texObj);
|
||||
(*ctx->Driver.DeleteTexture)(ctx, texObj);
|
||||
_mesa_HashRemove(ss->TexObjects, texName);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_mesa_DeleteHashTable(ss->TexObjects);
|
||||
|
||||
@@ -1529,99 +1538,48 @@ init_attrib_groups( GLcontext *ctx )
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Allocate the proxy textures. If we run out of memory part way through
|
||||
* the allocations clean up and return GL_FALSE.
|
||||
* Return: GL_TRUE=success, GL_FALSE=failure
|
||||
/**
|
||||
* Allocate the proxy textures for the given context.
|
||||
* \param ctx the context to allocate proxies for.
|
||||
* \return GL_TRUE if success, GL_FALSE if failure.
|
||||
*/
|
||||
static GLboolean
|
||||
alloc_proxy_textures( GLcontext *ctx )
|
||||
{
|
||||
GLboolean out_of_memory;
|
||||
GLint i;
|
||||
ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
|
||||
if (!ctx->Texture.Proxy1D)
|
||||
goto cleanup;
|
||||
|
||||
ctx->Texture.Proxy1D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_1D);
|
||||
if (!ctx->Texture.Proxy1D) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
|
||||
if (!ctx->Texture.Proxy2D)
|
||||
goto cleanup;
|
||||
|
||||
ctx->Texture.Proxy2D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_2D);
|
||||
if (!ctx->Texture.Proxy2D) {
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
|
||||
return GL_FALSE;
|
||||
}
|
||||
ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
|
||||
if (!ctx->Texture.Proxy3D)
|
||||
goto cleanup;
|
||||
|
||||
ctx->Texture.Proxy3D = _mesa_alloc_texture_object(NULL, 0, GL_TEXTURE_3D);
|
||||
if (!ctx->Texture.Proxy3D) {
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
|
||||
return GL_FALSE;
|
||||
}
|
||||
ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
|
||||
if (!ctx->Texture.ProxyCubeMap)
|
||||
goto cleanup;
|
||||
|
||||
ctx->Texture.ProxyCubeMap = _mesa_alloc_texture_object(NULL, 0,
|
||||
GL_TEXTURE_CUBE_MAP_ARB);
|
||||
if (!ctx->Texture.ProxyCubeMap) {
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy3D);
|
||||
return GL_FALSE;
|
||||
}
|
||||
ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
|
||||
if (!ctx->Texture.ProxyRect)
|
||||
goto cleanup;
|
||||
|
||||
ctx->Texture.ProxyRect = _mesa_alloc_texture_object(NULL, 0,
|
||||
GL_TEXTURE_RECTANGLE_NV);
|
||||
if (!ctx->Texture.ProxyRect) {
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy3D);
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.ProxyCubeMap);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
out_of_memory = GL_FALSE;
|
||||
for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
|
||||
ctx->Texture.Proxy1D->Image[i] = _mesa_alloc_texture_image();
|
||||
ctx->Texture.Proxy2D->Image[i] = _mesa_alloc_texture_image();
|
||||
ctx->Texture.Proxy3D->Image[i] = _mesa_alloc_texture_image();
|
||||
ctx->Texture.ProxyCubeMap->Image[i] = _mesa_alloc_texture_image();
|
||||
if (!ctx->Texture.Proxy1D->Image[i]
|
||||
|| !ctx->Texture.Proxy2D->Image[i]
|
||||
|| !ctx->Texture.Proxy3D->Image[i]
|
||||
|| !ctx->Texture.ProxyCubeMap->Image[i]) {
|
||||
out_of_memory = GL_TRUE;
|
||||
}
|
||||
}
|
||||
ctx->Texture.ProxyRect->Image[0] = _mesa_alloc_texture_image();
|
||||
if (!ctx->Texture.ProxyRect->Image[0])
|
||||
out_of_memory = GL_TRUE;
|
||||
|
||||
if (out_of_memory) {
|
||||
for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
|
||||
if (ctx->Texture.Proxy1D->Image[i]) {
|
||||
_mesa_free_texture_image(ctx->Texture.Proxy1D->Image[i]);
|
||||
}
|
||||
if (ctx->Texture.Proxy2D->Image[i]) {
|
||||
_mesa_free_texture_image(ctx->Texture.Proxy2D->Image[i]);
|
||||
}
|
||||
if (ctx->Texture.Proxy3D->Image[i]) {
|
||||
_mesa_free_texture_image(ctx->Texture.Proxy3D->Image[i]);
|
||||
}
|
||||
if (ctx->Texture.ProxyCubeMap->Image[i]) {
|
||||
_mesa_free_texture_image(ctx->Texture.ProxyCubeMap->Image[i]);
|
||||
}
|
||||
}
|
||||
if (ctx->Texture.ProxyRect->Image[0]) {
|
||||
_mesa_free_texture_image(ctx->Texture.ProxyRect->Image[0]);
|
||||
}
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy1D);
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy2D);
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.Proxy3D);
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.ProxyCubeMap);
|
||||
_mesa_free_texture_object(NULL, ctx->Texture.ProxyRect);
|
||||
return GL_FALSE;
|
||||
}
|
||||
else {
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (ctx->Texture.Proxy1D)
|
||||
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D);
|
||||
if (ctx->Texture.Proxy2D)
|
||||
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D);
|
||||
if (ctx->Texture.Proxy3D)
|
||||
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D);
|
||||
if (ctx->Texture.ProxyCubeMap)
|
||||
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap);
|
||||
if (ctx->Texture.ProxyRect)
|
||||
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -1695,14 +1653,23 @@ _mesa_initialize_context( GLcontext *ctx,
|
||||
ctx->DrawBuffer = NULL;
|
||||
ctx->ReadBuffer = NULL;
|
||||
|
||||
/* Set these pointers to defaults now in case they're not set since
|
||||
* we need them while creating the default textures.
|
||||
*/
|
||||
if (!ctx->Driver.NewTextureObject)
|
||||
ctx->Driver.NewTextureObject = _mesa_new_texture_object;
|
||||
if (!ctx->Driver.DeleteTexture)
|
||||
ctx->Driver.DeleteTexture = _mesa_delete_texture_object;
|
||||
if (!ctx->Driver.NewTextureImage)
|
||||
ctx->Driver.NewTextureImage = _mesa_new_texture_image;
|
||||
|
||||
if (share_list) {
|
||||
/* share state with another context */
|
||||
ctx->Shared = share_list->Shared;
|
||||
}
|
||||
else {
|
||||
/* allocate new, unshared state */
|
||||
ctx->Shared = alloc_shared_state();
|
||||
if (!ctx->Shared) {
|
||||
if (!alloc_shared_state( ctx )) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1710,13 +1677,6 @@ _mesa_initialize_context( GLcontext *ctx,
|
||||
ctx->Shared->RefCount++;
|
||||
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
|
||||
|
||||
/* Effectively bind the default textures to all texture units */
|
||||
ctx->Shared->Default1D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
|
||||
ctx->Shared->Default2D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
|
||||
ctx->Shared->Default3D->RefCount += MAX_TEXTURE_IMAGE_UNITS;
|
||||
ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_IMAGE_UNITS;
|
||||
ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_IMAGE_UNITS;
|
||||
|
||||
init_attrib_groups( ctx );
|
||||
|
||||
if (visual->doubleBufferMode) {
|
||||
@@ -1837,6 +1797,7 @@ _mesa_initialize_context( GLcontext *ctx,
|
||||
_glapi_add_entrypoint("glGetFenceivNV", 651);
|
||||
_glapi_add_entrypoint("glFinishFenceNV", 652);
|
||||
_glapi_add_entrypoint("glSetFenceNV", 653);
|
||||
/* XXX add NV_fragment_program and ARB_vertex_program functions */
|
||||
|
||||
/* Find the larger of Mesa's dispatch table and libGL's dispatch table.
|
||||
* In practice, this'll be the same for stand-alone Mesa. But for DRI
|
||||
@@ -1997,11 +1958,11 @@ _mesa_free_context_data( GLcontext *ctx )
|
||||
FREE( ctx->_ShineTabList );
|
||||
|
||||
/* Free proxy texture objects */
|
||||
_mesa_free_texture_object( NULL, ctx->Texture.Proxy1D );
|
||||
_mesa_free_texture_object( NULL, ctx->Texture.Proxy2D );
|
||||
_mesa_free_texture_object( NULL, ctx->Texture.Proxy3D );
|
||||
_mesa_free_texture_object( NULL, ctx->Texture.ProxyCubeMap );
|
||||
_mesa_free_texture_object( NULL, ctx->Texture.ProxyRect );
|
||||
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D );
|
||||
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D );
|
||||
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D );
|
||||
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap );
|
||||
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect );
|
||||
|
||||
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
|
||||
_mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* $Id: dd.h,v 1.74 2002/10/11 17:41:04 brianp Exp $ */
|
||||
/* $Id: dd.h,v 1.75 2003/04/01 16:41:52 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -51,7 +51,6 @@ struct gl_pixelstore_attrib;
|
||||
* Device Driver function table.
|
||||
*/
|
||||
struct dd_function_table {
|
||||
|
||||
const GLubyte * (*GetString)( GLcontext *ctx, GLenum name );
|
||||
/* Return a string as needed by glGetString().
|
||||
* Only the GL_RENDERER token must be implemented. Otherwise,
|
||||
@@ -354,8 +353,12 @@ struct dd_function_table {
|
||||
/* Called by glBindTexture().
|
||||
*/
|
||||
|
||||
void (*CreateTexture)( GLcontext *ctx, struct gl_texture_object *tObj );
|
||||
/* Called when a texture object is created.
|
||||
struct gl_texture_object * (*NewTextureObject)( GLcontext *ctx, GLuint name,
|
||||
GLenum target );
|
||||
/* Called to allocate a new texture object.
|
||||
* NOTE: this function pointer should be initialized by drivers _BEFORE_
|
||||
* calling _mesa_initialize_context() since context initialization involves
|
||||
* allocating some texture objects!
|
||||
*/
|
||||
|
||||
void (*DeleteTexture)( GLcontext *ctx, struct gl_texture_object *tObj );
|
||||
@@ -363,6 +366,10 @@ struct dd_function_table {
|
||||
* should free anything attached to the DriverData pointers.
|
||||
*/
|
||||
|
||||
struct gl_texture_image * (*NewTextureImage)( GLcontext *ctx );
|
||||
/* Called to allocate a new texture image object.
|
||||
*/
|
||||
|
||||
GLboolean (*IsTextureResident)( GLcontext *ctx,
|
||||
struct gl_texture_object *t );
|
||||
/* Called by glAreTextureResident().
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* $Id: teximage.c,v 1.126 2003/03/01 01:50:22 brianp Exp $ */
|
||||
/* $Id: teximage.c,v 1.127 2003/04/01 16:41:53 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -415,19 +415,26 @@ _mesa_set_tex_image(struct gl_texture_object *tObj,
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Return new gl_texture_image struct with all fields initialized to zero.
|
||||
* Called via ctx->Driver.NewTextureImage() unless overriden by a device
|
||||
* driver.
|
||||
*/
|
||||
struct gl_texture_image *
|
||||
_mesa_alloc_texture_image( void )
|
||||
_mesa_new_texture_image( GLcontext *ctx )
|
||||
{
|
||||
(void) ctx;
|
||||
return CALLOC_STRUCT(gl_texture_image);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Delete/free the given texture image and associated image data if it's not
|
||||
* marked as client data.
|
||||
*/
|
||||
void
|
||||
_mesa_free_texture_image( struct gl_texture_image *teximage )
|
||||
_mesa_delete_texture_image( struct gl_texture_image *teximage )
|
||||
{
|
||||
if (teximage->Data && !teximage->IsClientData) {
|
||||
MESA_PBUFFER_FREE( teximage->Data );
|
||||
@@ -577,6 +584,118 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Like _mesa_select_tex_image() but if the image doesn't exist, allocate
|
||||
* it and install it. Only return NULL if passed a bad parameter or run
|
||||
* out of memory.
|
||||
*/
|
||||
struct gl_texture_image *
|
||||
_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
|
||||
GLenum target, GLint level)
|
||||
{
|
||||
struct gl_texture_image *texImage;
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
if (!texImage) {
|
||||
struct gl_texture_object *texObj;
|
||||
texImage = ctx->Driver.NewTextureImage(ctx);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
|
||||
return NULL;
|
||||
}
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
ASSERT(texObj);
|
||||
_mesa_set_tex_image(texObj, target, level, texImage);
|
||||
}
|
||||
return texImage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return pointer to the specified proxy texture image.
|
||||
* Note that proxy textures are per-context, not per-texture unit.
|
||||
* \return pointer to texture image or NULL if invalid target, invalid
|
||||
* level, or out of memory.
|
||||
*/
|
||||
struct gl_texture_image *
|
||||
_mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level)
|
||||
{
|
||||
struct gl_texture_image *texImage;
|
||||
|
||||
if (level < 0 )
|
||||
return NULL;
|
||||
|
||||
switch (target) {
|
||||
case GL_PROXY_TEXTURE_1D:
|
||||
if (level >= ctx->Const.MaxTextureLevels)
|
||||
return NULL;
|
||||
texImage = ctx->Texture.Proxy1D->Image[level];
|
||||
if (!texImage) {
|
||||
texImage = ctx->Driver.NewTextureImage(ctx);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
|
||||
return NULL;
|
||||
}
|
||||
ctx->Texture.Proxy1D->Image[level] = texImage;
|
||||
}
|
||||
return texImage;
|
||||
case GL_PROXY_TEXTURE_2D:
|
||||
if (level >= ctx->Const.MaxTextureLevels)
|
||||
return NULL;
|
||||
texImage = ctx->Texture.Proxy2D->Image[level];
|
||||
if (!texImage) {
|
||||
texImage = ctx->Driver.NewTextureImage(ctx);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
|
||||
return NULL;
|
||||
}
|
||||
ctx->Texture.Proxy2D->Image[level] = texImage;
|
||||
}
|
||||
return texImage;
|
||||
case GL_PROXY_TEXTURE_3D:
|
||||
if (level >= ctx->Const.Max3DTextureLevels)
|
||||
return NULL;
|
||||
texImage = ctx->Texture.Proxy3D->Image[level];
|
||||
if (!texImage) {
|
||||
texImage = ctx->Driver.NewTextureImage(ctx);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
|
||||
return NULL;
|
||||
}
|
||||
ctx->Texture.Proxy3D->Image[level] = texImage;
|
||||
}
|
||||
return texImage;
|
||||
case GL_PROXY_TEXTURE_CUBE_MAP:
|
||||
if (level >= ctx->Const.MaxCubeTextureLevels)
|
||||
return NULL;
|
||||
texImage = ctx->Texture.ProxyCubeMap->Image[level];
|
||||
if (!texImage) {
|
||||
texImage = ctx->Driver.NewTextureImage(ctx);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
|
||||
return NULL;
|
||||
}
|
||||
ctx->Texture.ProxyCubeMap->Image[level] = texImage;
|
||||
}
|
||||
return texImage;
|
||||
case GL_PROXY_TEXTURE_RECTANGLE_NV:
|
||||
if (level > 0)
|
||||
return NULL;
|
||||
texImage = ctx->Texture.ProxyRect->Image[level];
|
||||
if (!texImage) {
|
||||
texImage = ctx->Driver.NewTextureImage(ctx);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
|
||||
return NULL;
|
||||
}
|
||||
ctx->Texture.ProxyRect->Image[level] = texImage;
|
||||
}
|
||||
return texImage;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the maximum number of allows mipmap levels for the given
|
||||
* texture target.
|
||||
@@ -1167,10 +1286,8 @@ subtexture_error_check( GLcontext *ctx, GLuint dimensions,
|
||||
|
||||
if (destTex->IsCompressed) {
|
||||
const struct gl_texture_unit *texUnit;
|
||||
const struct gl_texture_object *texObj;
|
||||
const struct gl_texture_image *texImage;
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
|
||||
if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
|
||||
@@ -1637,16 +1754,12 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
|
||||
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
|
||||
|
||||
if (!texImage) {
|
||||
texImage = _mesa_alloc_texture_image();
|
||||
texObj->Image[level] = texImage;
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (texImage->Data && !texImage->IsClientData) {
|
||||
/* free the old texture data */
|
||||
MESA_PBUFFER_FREE(texImage->Data);
|
||||
@@ -1690,9 +1803,10 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
|
||||
}
|
||||
if (error) {
|
||||
/* if error, clear all proxy texture image parameters */
|
||||
if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
|
||||
clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]);
|
||||
}
|
||||
struct gl_texture_image *texImage;
|
||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
||||
if (texImage)
|
||||
clear_teximage_fields(texImage);
|
||||
}
|
||||
else {
|
||||
/* no error, set the tex image parameters */
|
||||
@@ -1746,16 +1860,11 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
|
||||
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
|
||||
if (!texImage) {
|
||||
texImage = _mesa_alloc_texture_image();
|
||||
_mesa_set_tex_image(texObj, target, level, texImage);
|
||||
texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (texImage->Data && !texImage->IsClientData) {
|
||||
/* free the old texture data */
|
||||
MESA_PBUFFER_FREE(texImage->Data);
|
||||
@@ -1803,12 +1912,11 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
|
||||
}
|
||||
if (error) {
|
||||
/* if error, clear all proxy texture image parameters */
|
||||
const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ?
|
||||
ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels;
|
||||
if (level >= 0 && level < maxLevels) {
|
||||
struct gl_texture_image *texImage;
|
||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
||||
if (texImage)
|
||||
clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* no error, set the tex image parameters */
|
||||
struct gl_texture_unit *texUnit;
|
||||
@@ -1852,16 +1960,11 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
|
||||
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
|
||||
if (!texImage) {
|
||||
texImage = _mesa_alloc_texture_image();
|
||||
texObj->Image[level] = texImage;
|
||||
texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (texImage->Data && !texImage->IsClientData) {
|
||||
MESA_PBUFFER_FREE(texImage->Data);
|
||||
}
|
||||
@@ -1904,9 +2007,10 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
|
||||
}
|
||||
if (error) {
|
||||
/* if error, clear all proxy texture image parameters */
|
||||
if (level >= 0 && level < ctx->Const.Max3DTextureLevels) {
|
||||
clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]);
|
||||
}
|
||||
struct gl_texture_image *texImage;
|
||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
||||
if (texImage)
|
||||
clear_teximage_fields(texImage);
|
||||
}
|
||||
else {
|
||||
/* no error, set the tex image parameters */
|
||||
@@ -2102,15 +2206,11 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
|
||||
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
if (!texImage) {
|
||||
texImage = _mesa_alloc_texture_image();
|
||||
_mesa_set_tex_image(texObj, target, level, texImage);
|
||||
texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (texImage->Data && !texImage->IsClientData) {
|
||||
/* free the old texture data */
|
||||
MESA_PBUFFER_FREE(texImage->Data);
|
||||
@@ -2166,15 +2266,11 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
|
||||
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
if (!texImage) {
|
||||
texImage = _mesa_alloc_texture_image();
|
||||
_mesa_set_tex_image(texObj, target, level, texImage);
|
||||
texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (texImage->Data && !texImage->IsClientData) {
|
||||
/* free the old texture data */
|
||||
MESA_PBUFFER_FREE(texImage->Data);
|
||||
@@ -2228,6 +2324,7 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
ASSERT(texImage);
|
||||
|
||||
/* If we have a border, xoffset=-1 is legal. Bias by border width */
|
||||
xoffset += texImage->Border;
|
||||
@@ -2264,6 +2361,7 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
ASSERT(texImage);
|
||||
|
||||
/* If we have a border, xoffset=-1 is legal. Bias by border width */
|
||||
xoffset += texImage->Border;
|
||||
@@ -2302,6 +2400,7 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
ASSERT(texImage);
|
||||
|
||||
/* If we have a border, xoffset=-1 is legal. Bias by border width */
|
||||
xoffset += texImage->Border;
|
||||
@@ -2509,16 +2608,11 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
|
||||
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
|
||||
if (!texImage) {
|
||||
texImage = _mesa_alloc_texture_image();
|
||||
texObj->Image[level] = texImage;
|
||||
texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (texImage->Data && !texImage->IsClientData) {
|
||||
MESA_PBUFFER_FREE(texImage->Data);
|
||||
}
|
||||
@@ -2549,9 +2643,10 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
|
||||
}
|
||||
if (error) {
|
||||
/* if error, clear all proxy texture image parameters */
|
||||
if (level >= 0 && level < ctx->Const.MaxTextureLevels) {
|
||||
clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]);
|
||||
}
|
||||
struct gl_texture_image *texImage;
|
||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
||||
if (texImage)
|
||||
clear_teximage_fields(texImage);
|
||||
}
|
||||
else {
|
||||
/* store the teximage parameters */
|
||||
@@ -2595,16 +2690,11 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
|
||||
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
|
||||
if (!texImage) {
|
||||
texImage = _mesa_alloc_texture_image();
|
||||
texObj->Image[level] = texImage;
|
||||
texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (texImage->Data && !texImage->IsClientData) {
|
||||
MESA_PBUFFER_FREE(texImage->Data);
|
||||
}
|
||||
@@ -2637,11 +2727,10 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
|
||||
}
|
||||
if (error) {
|
||||
/* if error, clear all proxy texture image parameters */
|
||||
const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ?
|
||||
ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels;
|
||||
if (level >= 0 && level < maxLevels) {
|
||||
clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]);
|
||||
}
|
||||
struct gl_texture_image *texImage;
|
||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
||||
if (texImage)
|
||||
clear_teximage_fields(texImage);
|
||||
}
|
||||
else {
|
||||
/* store the teximage parameters */
|
||||
@@ -2682,16 +2771,11 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
|
||||
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
|
||||
if (!texImage) {
|
||||
texImage = _mesa_alloc_texture_image();
|
||||
texObj->Image[level] = texImage;
|
||||
texImage = _mesa_get_tex_image(ctx, texUnit, target, level);
|
||||
if (!texImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (texImage->Data && !texImage->IsClientData) {
|
||||
MESA_PBUFFER_FREE(texImage->Data);
|
||||
}
|
||||
@@ -2723,9 +2807,10 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
|
||||
}
|
||||
if (error) {
|
||||
/* if error, clear all proxy texture image parameters */
|
||||
if (level >= 0 && level < ctx->Const.Max3DTextureLevels) {
|
||||
clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]);
|
||||
}
|
||||
struct gl_texture_image *texImage;
|
||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
||||
if (texImage)
|
||||
clear_teximage_fields(texImage);
|
||||
}
|
||||
else {
|
||||
/* store the teximage parameters */
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* $Id: teximage.h,v 1.22 2002/10/18 18:03:07 brianp Exp $ */
|
||||
/* $Id: teximage.h,v 1.23 2003/04/01 16:41:54 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -40,11 +40,11 @@ _mesa_base_tex_format( GLcontext *ctx, GLint format );
|
||||
|
||||
|
||||
extern struct gl_texture_image *
|
||||
_mesa_alloc_texture_image( void );
|
||||
_mesa_new_texture_image( GLcontext *ctx );
|
||||
|
||||
|
||||
extern void
|
||||
_mesa_free_texture_image( struct gl_texture_image *teximage );
|
||||
_mesa_delete_texture_image( struct gl_texture_image *teximage );
|
||||
|
||||
|
||||
extern void
|
||||
@@ -70,6 +70,15 @@ _mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
|
||||
GLenum target, GLint level);
|
||||
|
||||
|
||||
extern struct gl_texture_image *
|
||||
_mesa_get_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit,
|
||||
GLenum target, GLint level);
|
||||
|
||||
|
||||
extern struct gl_texture_image *
|
||||
_mesa_get_proxy_tex_image(GLcontext *ctx, GLenum target, GLint level);
|
||||
|
||||
|
||||
extern GLint
|
||||
_mesa_max_texture_levels(GLcontext *ctx, GLenum target);
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* $Id: texobj.c,v 1.66 2003/03/10 00:26:24 brianp Exp $ */
|
||||
/* $Id: texobj.c,v 1.67 2003/04/01 16:41:55 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -37,23 +37,37 @@
|
||||
#include "mtypes.h"
|
||||
|
||||
|
||||
/*
|
||||
* Allocate a new texture object and add it to the linked list of texture
|
||||
* objects. If name>0 then also insert the new texture object into the hash
|
||||
* table.
|
||||
* Input: shared - the shared GL state structure to contain the texture object
|
||||
* name - integer name for the texture object
|
||||
* target - either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
|
||||
/**
|
||||
* Allocate and initialize a new texture object
|
||||
* Called via ctx->Driver.NewTextureObject, unless overridden by a device
|
||||
* driver.
|
||||
* \param ctx the rendering context
|
||||
* \param name the integer name for the texture object
|
||||
* \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
|
||||
* GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV
|
||||
* zero is ok for the sake of GenTextures()
|
||||
* Return: pointer to new texture object
|
||||
* \return pointer to new texture object
|
||||
*/
|
||||
struct gl_texture_object *
|
||||
_mesa_alloc_texture_object( struct gl_shared_state *shared,
|
||||
GLuint name, GLenum target )
|
||||
_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target )
|
||||
{
|
||||
struct gl_texture_object *obj;
|
||||
obj = CALLOC_STRUCT(gl_texture_object);
|
||||
_mesa_initialize_texture_object(obj, name, target);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a texture object to default values.
|
||||
* \param obj the texture object
|
||||
* \param name the texture name
|
||||
* \param target the texture target
|
||||
*/
|
||||
void
|
||||
_mesa_initialize_texture_object( struct gl_texture_object *obj,
|
||||
GLuint name, GLenum target )
|
||||
{
|
||||
ASSERT(target == 0 ||
|
||||
target == GL_TEXTURE_1D ||
|
||||
target == GL_TEXTURE_2D ||
|
||||
@@ -61,9 +75,6 @@ _mesa_alloc_texture_object( struct gl_shared_state *shared,
|
||||
target == GL_TEXTURE_CUBE_MAP_ARB ||
|
||||
target == GL_TEXTURE_RECTANGLE_NV);
|
||||
|
||||
obj = CALLOC_STRUCT(gl_texture_object);
|
||||
|
||||
if (obj) {
|
||||
/* init the non-zero fields */
|
||||
_glthread_INIT_MUTEX(obj->Mutex);
|
||||
obj->RefCount = 1;
|
||||
@@ -95,80 +106,93 @@ _mesa_alloc_texture_object( struct gl_shared_state *shared,
|
||||
obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */
|
||||
obj->ShadowAmbient = 0.0F; /* ARB/SGIX_shadow_ambient */
|
||||
_mesa_init_colortable(&obj->Palette);
|
||||
|
||||
/* insert into linked list */
|
||||
if (shared) {
|
||||
_glthread_LOCK_MUTEX(shared->Mutex);
|
||||
obj->Next = shared->TexObjectList;
|
||||
shared->TexObjectList = obj;
|
||||
_glthread_UNLOCK_MUTEX(shared->Mutex);
|
||||
}
|
||||
|
||||
if (name > 0) {
|
||||
/* insert into hash table */
|
||||
_mesa_HashInsert(shared->TexObjects, name, obj);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Deallocate a texture object struct and remove it from the given
|
||||
* shared GL state.
|
||||
* Input: shared - the shared GL state to which the object belongs
|
||||
* t - the texture object to delete
|
||||
* Deallocate a texture object. It should have already been removed from
|
||||
* the texture object pool.
|
||||
* \param texObj the texture object to deallocate
|
||||
*/
|
||||
void _mesa_free_texture_object( struct gl_shared_state *shared,
|
||||
struct gl_texture_object *t )
|
||||
void
|
||||
_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
|
||||
{
|
||||
GLuint i;
|
||||
|
||||
(void) ctx;
|
||||
|
||||
assert(texObj);
|
||||
|
||||
_mesa_free_colortable_data(&texObj->Palette);
|
||||
|
||||
/* free the texture images */
|
||||
for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
|
||||
if (texObj->Image[i]) {
|
||||
_mesa_delete_texture_image( texObj->Image[i] );
|
||||
}
|
||||
}
|
||||
|
||||
/* destroy the mutex -- it may have allocated memory (eg on bsd) */
|
||||
_glthread_DESTROY_MUTEX(texObj->Mutex);
|
||||
|
||||
/* free this object */
|
||||
_mesa_free(texObj);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the given texture object to the texture object pool.
|
||||
*/
|
||||
void
|
||||
_mesa_save_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
|
||||
{
|
||||
/* insert into linked list */
|
||||
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
|
||||
texObj->Next = ctx->Shared->TexObjectList;
|
||||
ctx->Shared->TexObjectList = texObj;
|
||||
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
|
||||
|
||||
if (texObj->Name > 0) {
|
||||
/* insert into hash table */
|
||||
_mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the given texture object from the texture object pool.
|
||||
* Do not deallocate the texture object though.
|
||||
*/
|
||||
void
|
||||
_mesa_remove_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
|
||||
{
|
||||
struct gl_texture_object *tprev, *tcurr;
|
||||
|
||||
assert(t);
|
||||
_glthread_LOCK_MUTEX(ctx->Shared->Mutex);
|
||||
|
||||
/* unlink t from the linked list */
|
||||
if (shared) {
|
||||
_glthread_LOCK_MUTEX(shared->Mutex);
|
||||
/* unlink from the linked list */
|
||||
tprev = NULL;
|
||||
tcurr = shared->TexObjectList;
|
||||
tcurr = ctx->Shared->TexObjectList;
|
||||
while (tcurr) {
|
||||
if (tcurr==t) {
|
||||
if (tcurr == texObj) {
|
||||
if (tprev) {
|
||||
tprev->Next = t->Next;
|
||||
tprev->Next = texObj->Next;
|
||||
}
|
||||
else {
|
||||
shared->TexObjectList = t->Next;
|
||||
ctx->Shared->TexObjectList = texObj->Next;
|
||||
}
|
||||
break;
|
||||
}
|
||||
tprev = tcurr;
|
||||
tcurr = tcurr->Next;
|
||||
}
|
||||
_glthread_UNLOCK_MUTEX(shared->Mutex);
|
||||
}
|
||||
|
||||
if (t->Name) {
|
||||
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
|
||||
|
||||
if (texObj->Name > 0) {
|
||||
/* remove from hash table */
|
||||
_mesa_HashRemove(shared->TexObjects, t->Name);
|
||||
_mesa_HashRemove(ctx->Shared->TexObjects, texObj->Name);
|
||||
}
|
||||
|
||||
_mesa_free_colortable_data(&t->Palette);
|
||||
|
||||
/* free the texture images */
|
||||
{
|
||||
GLuint i;
|
||||
for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
|
||||
if (t->Image[i]) {
|
||||
_mesa_free_texture_image( t->Image[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* destroy the mutex -- it may have allocated memory (eg on bsd) */
|
||||
_glthread_DESTROY_MUTEX(t->Mutex);
|
||||
|
||||
/* free this object */
|
||||
FREE( t );
|
||||
}
|
||||
|
||||
|
||||
@@ -531,10 +555,16 @@ _mesa_GenTextures( GLsizei n, GLuint *texName )
|
||||
}
|
||||
|
||||
/* Allocate new, empty texture objects */
|
||||
for (i=0;i<n;i++) {
|
||||
for (i = 0; i < n; i++) {
|
||||
struct gl_texture_object *texObj;
|
||||
GLuint name = first + i;
|
||||
GLenum target = 0;
|
||||
(void) _mesa_alloc_texture_object( ctx->Shared, name, target);
|
||||
texObj = (*ctx->Driver.NewTextureObject)( ctx, name, target);
|
||||
if (!texObj) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
|
||||
return;
|
||||
}
|
||||
_mesa_save_texture_object(ctx, texObj);
|
||||
}
|
||||
|
||||
_glthread_UNLOCK_MUTEX(GenTexturesLock);
|
||||
@@ -610,9 +640,9 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *texName)
|
||||
|
||||
if (delObj->RefCount == 0) {
|
||||
ASSERT(delObj->Name != 0);
|
||||
if (ctx->Driver.DeleteTexture)
|
||||
(*ctx->Driver.DeleteTexture)( ctx, delObj );
|
||||
_mesa_free_texture_object(ctx->Shared, delObj);
|
||||
_mesa_remove_texture_object(ctx, delObj);
|
||||
ASSERT(ctx->Driver.DeleteTexture);
|
||||
(*ctx->Driver.DeleteTexture)(ctx, delObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -717,12 +747,12 @@ _mesa_BindTexture( GLenum target, GLuint texName )
|
||||
}
|
||||
else {
|
||||
/* if this is a new texture id, allocate a texture object now */
|
||||
newTexObj = _mesa_alloc_texture_object( ctx->Shared, texName,
|
||||
target);
|
||||
newTexObj = (*ctx->Driver.NewTextureObject)(ctx, texName, target);
|
||||
if (!newTexObj) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
|
||||
return;
|
||||
}
|
||||
_mesa_save_texture_object(ctx, newTexObj);
|
||||
}
|
||||
newTexObj->Target = target;
|
||||
}
|
||||
@@ -762,11 +792,10 @@ _mesa_BindTexture( GLenum target, GLuint texName )
|
||||
assert(oldTexObj->RefCount >= 0);
|
||||
if (oldTexObj->RefCount == 0) {
|
||||
assert(oldTexObj->Name != 0);
|
||||
if (ctx->Driver.DeleteTexture) {
|
||||
_mesa_remove_texture_object(ctx, oldTexObj);
|
||||
ASSERT(ctx->Driver.DeleteTexture);
|
||||
(*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
|
||||
}
|
||||
_mesa_free_texture_object(ctx->Shared, oldTexObj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* $Id: texobj.h,v 1.8 2002/06/17 23:36:31 brianp Exp $ */
|
||||
/* $Id: texobj.h,v 1.9 2003/04/01 16:41:55 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -38,23 +38,28 @@
|
||||
*/
|
||||
|
||||
extern struct gl_texture_object *
|
||||
_mesa_alloc_texture_object( struct gl_shared_state *shared, GLuint name,
|
||||
GLenum target );
|
||||
|
||||
_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target );
|
||||
|
||||
extern void
|
||||
_mesa_free_texture_object( struct gl_shared_state *shared,
|
||||
struct gl_texture_object *t );
|
||||
_mesa_initialize_texture_object( struct gl_texture_object *obj,
|
||||
GLuint name, GLenum target );
|
||||
|
||||
extern void
|
||||
_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *obj );
|
||||
|
||||
extern void
|
||||
_mesa_save_texture_object( GLcontext *ctx, struct gl_texture_object *obj );
|
||||
|
||||
extern void
|
||||
_mesa_remove_texture_object( GLcontext *ctx, struct gl_texture_object *obj );
|
||||
|
||||
extern void
|
||||
_mesa_copy_texture_object( struct gl_texture_object *dest,
|
||||
const struct gl_texture_object *src );
|
||||
|
||||
|
||||
extern void
|
||||
_mesa_test_texobj_completeness( const GLcontext *ctx,
|
||||
struct gl_texture_object *t );
|
||||
struct gl_texture_object *obj );
|
||||
|
||||
|
||||
/*
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* $Id: texstore.c,v 1.54 2003/03/04 19:16:23 brianp Exp $ */
|
||||
/* $Id: texstore.c,v 1.55 2003/04/01 16:41:55 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -482,6 +482,7 @@ _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
|
||||
baseInternalFormat == GL_ALPHA ||
|
||||
baseInternalFormat == GL_RGB ||
|
||||
baseInternalFormat == GL_RGBA ||
|
||||
baseInternalFormat == GL_COLOR_INDEX ||
|
||||
baseInternalFormat == GL_DEPTH_COMPONENT);
|
||||
|
||||
if (transferOps & IMAGE_CONVOLUTION_BIT) {
|
||||
@@ -1274,16 +1275,12 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
|
||||
GLint internalFormat, GLenum format, GLenum type,
|
||||
GLint width, GLint height, GLint depth, GLint border)
|
||||
{
|
||||
struct gl_texture_unit *texUnit;
|
||||
struct gl_texture_object *texObj;
|
||||
struct gl_texture_image *texImage;
|
||||
|
||||
(void) format;
|
||||
(void) type;
|
||||
|
||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||
texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||
texImage = _mesa_get_proxy_tex_image(ctx, target, level);
|
||||
|
||||
/* We always pass.
|
||||
* The core Mesa code will have already tested the image size, etc.
|
||||
@@ -2011,15 +2008,11 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target,
|
||||
}
|
||||
|
||||
/* get dest gl_texture_image */
|
||||
dstImage = _mesa_select_tex_image(ctx, texUnit, target, level+1);
|
||||
if (!dstImage) {
|
||||
dstImage = _mesa_alloc_texture_image();
|
||||
dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
|
||||
if (!dstImage) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
|
||||
return;
|
||||
}
|
||||
_mesa_set_tex_image(texObj, target, level + 1, dstImage);
|
||||
}
|
||||
|
||||
/* Free old image data */
|
||||
if (dstImage->Data)
|
||||
|
Reference in New Issue
Block a user