texobj.c revision 3ec0631e955cb79cf6009e391cd9b4f6a263b989
16dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
26dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \file texobj.c
36dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Texture object management.
46dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell */
56dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
6afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
7afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Mesa 3-D graphics library
8f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul * Version:  6.2
95e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen *
10c929f13701634a145a217ebb1ddec80742234d5dBrian Paul * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
115e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen *
12afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Permission is hereby granted, free of charge, to any person obtaining a
13afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * copy of this software and associated documentation files (the "Software"),
14afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * to deal in the Software without restriction, including without limitation
15afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * and/or sell copies of the Software, and to permit persons to whom the
17afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Software is furnished to do so, subject to the following conditions:
185e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen *
19afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * The above copyright notice and this permission notice shall be included
20afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * in all copies or substantial portions of the Software.
215e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen *
22afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
29afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
306dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
31fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul#include "glheader.h"
324bdcfe50f8886e43714f9b7edd25cbff19e6a97dBrian Paul#include "colortab.h"
33afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "context.h"
34afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "enums.h"
35afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "hash.h"
363c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h"
37ebb248aa5c018dc676d389221d76ed329059789eBrian Paul#include "macros.h"
38afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "teximage.h"
39afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "texstate.h"
40afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "texobj.h"
415e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen#include "mtypes.h"
42afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
43afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
446dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**********************************************************************/
456dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** \name Internal functions */
466dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@{*/
476dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
48a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/**
498a033fa13514e3b78612ba1678182c9ea8290cd4Brian Paul * Allocate and initialize a new texture object.  But don't put it into the
508a033fa13514e3b78612ba1678182c9ea8290cd4Brian Paul * texture object hash table.
516dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
52a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * Called via ctx->Driver.NewTextureObject, unless overridden by a device
53a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * driver.
546dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
556dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param shared the shared GL state structure to contain the texture object
566dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param name integer name for the texture object
576dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
586dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV.  zero is ok for the sake
596dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * of GenTextures()
606dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
616dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \return pointer to new texture object.
62afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
63afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstruct gl_texture_object *
64a3f137094cd965d27e1b088499dd609b81a91906Brian Paul_mesa_new_texture_object( GLcontext *ctx, GLuint name, GLenum target )
65afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
66afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   struct gl_texture_object *obj;
67a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
689c0b83556dae35cf7260567f30fc156efa8c9742Brian Paul   obj = MALLOC_STRUCT(gl_texture_object);
69a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   _mesa_initialize_texture_object(obj, name, target);
70a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   return obj;
71a3f137094cd965d27e1b088499dd609b81a91906Brian Paul}
72afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
73a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
74a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/**
75f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul * Initialize a new texture object to default values.
76a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * \param obj  the texture object
77a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * \param name  the texture name
78a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * \param target  the texture target
79a3f137094cd965d27e1b088499dd609b81a91906Brian Paul */
80a3f137094cd965d27e1b088499dd609b81a91906Brian Paulvoid
81a3f137094cd965d27e1b088499dd609b81a91906Brian Paul_mesa_initialize_texture_object( struct gl_texture_object *obj,
82a3f137094cd965d27e1b088499dd609b81a91906Brian Paul                                 GLuint name, GLenum target )
83a3f137094cd965d27e1b088499dd609b81a91906Brian Paul{
848afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   ASSERT(target == 0 ||
858afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul          target == GL_TEXTURE_1D ||
868afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul          target == GL_TEXTURE_2D ||
878afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul          target == GL_TEXTURE_3D ||
888afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul          target == GL_TEXTURE_CUBE_MAP_ARB ||
898afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul          target == GL_TEXTURE_RECTANGLE_NV);
90420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul
91f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul   _mesa_bzero(obj, sizeof(*obj));
92a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* init the non-zero fields */
93a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   _glthread_INIT_MUTEX(obj->Mutex);
94a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->RefCount = 1;
95a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->Name = name;
96a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->Target = target;
97a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->Priority = 1.0F;
98a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   if (target == GL_TEXTURE_RECTANGLE_NV) {
99a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      obj->WrapS = GL_CLAMP_TO_EDGE;
100a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      obj->WrapT = GL_CLAMP_TO_EDGE;
101a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      obj->WrapR = GL_CLAMP_TO_EDGE;
102a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      obj->MinFilter = GL_LINEAR;
103afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
104a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   else {
105a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      obj->WrapS = GL_REPEAT;
106a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      obj->WrapT = GL_REPEAT;
107a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      obj->WrapR = GL_REPEAT;
108a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
109a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   }
110a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->MagFilter = GL_LINEAR;
111a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->MinLod = -1000.0;
112a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->MaxLod = 1000.0;
113781fb93877ea3a6faeefcdb48d9b463da7d954a3Brian Paul   obj->LodBias = 0.0;
114a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->BaseLevel = 0;
115a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->MaxLevel = 1000;
116a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->MaxAnisotropy = 1.0;
117a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->CompareFlag = GL_FALSE;                      /* SGIX_shadow */
118a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX;  /* SGIX_shadow */
119f0805670a1b8e624c6f9a468a14c4bfbca446d1cBrian Paul   obj->CompareMode = GL_NONE;         /* ARB_shadow */
120a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->CompareFunc = GL_LEQUAL;       /* ARB_shadow */
121a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->DepthMode = GL_LUMINANCE;      /* ARB_depth_texture */
122a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->ShadowAmbient = 0.0F;          /* ARB/SGIX_shadow_ambient */
12305944c031cd6bea985050f0e88a19f0794f57887Brian Paul   _mesa_init_colortable(&obj->Palette);
124afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
125afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
126afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1276dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
1286dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Deallocate a texture object struct.  It should have already been
1296dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * removed from the texture object pool.
1306dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
1316dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param shared the shared GL state to which the object belongs.
1326dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texOjb the texture object to delete.
133afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
134a3f137094cd965d27e1b088499dd609b81a91906Brian Paulvoid
135a3f137094cd965d27e1b088499dd609b81a91906Brian Paul_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
136afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
13718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   GLuint i, face;
138afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
139a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   (void) ctx;
140a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
14105944c031cd6bea985050f0e88a19f0794f57887Brian Paul   _mesa_free_colortable_data(&texObj->Palette);
142a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
143a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* free the texture images */
14418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   for (face = 0; face < 6; face++) {
14518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
14618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	 if (texObj->Image[face][i]) {
14718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	    _mesa_delete_texture_image( texObj->Image[face][i] );
14818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	 }
149afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
150afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
151afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
152a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* destroy the mutex -- it may have allocated memory (eg on bsd) */
153a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   _glthread_DESTROY_MUTEX(texObj->Mutex);
154a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
155a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* free this object */
156a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   _mesa_free(texObj);
157a3f137094cd965d27e1b088499dd609b81a91906Brian Paul}
158a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
159a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
160a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/**
161a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * Add the given texture object to the texture object pool.
162a3f137094cd965d27e1b088499dd609b81a91906Brian Paul */
163a3f137094cd965d27e1b088499dd609b81a91906Brian Paulvoid
164a3f137094cd965d27e1b088499dd609b81a91906Brian Paul_mesa_save_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
165a3f137094cd965d27e1b088499dd609b81a91906Brian Paul{
166a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* insert into linked list */
167a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
168a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   texObj->Next = ctx->Shared->TexObjectList;
169a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   ctx->Shared->TexObjectList = texObj;
170a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
171a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
172a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   if (texObj->Name > 0) {
173a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      /* insert into hash table */
174a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
175afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
176a3f137094cd965d27e1b088499dd609b81a91906Brian Paul}
177afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1784bdcfe50f8886e43714f9b7edd25cbff19e6a97dBrian Paul
179a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/**
180a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * Remove the given texture object from the texture object pool.
181a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * Do not deallocate the texture object though.
182a3f137094cd965d27e1b088499dd609b81a91906Brian Paul */
183a3f137094cd965d27e1b088499dd609b81a91906Brian Paulvoid
184a3f137094cd965d27e1b088499dd609b81a91906Brian Paul_mesa_remove_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
185a3f137094cd965d27e1b088499dd609b81a91906Brian Paul{
186a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   struct gl_texture_object *tprev, *tcurr;
187a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
188a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
189a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
190a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* unlink from the linked list */
191a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   tprev = NULL;
192a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   tcurr = ctx->Shared->TexObjectList;
193a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   while (tcurr) {
194a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      if (tcurr == texObj) {
195a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         if (tprev) {
196a3f137094cd965d27e1b088499dd609b81a91906Brian Paul            tprev->Next = texObj->Next;
197afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
198a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         else {
199a3f137094cd965d27e1b088499dd609b81a91906Brian Paul            ctx->Shared->TexObjectList = texObj->Next;
200a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         }
201a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         break;
202afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
203a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      tprev = tcurr;
204a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      tcurr = tcurr->Next;
205afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
206a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul
207a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
208e15fd85727636627e0cc7d4fd2d5367e178e42ccKeith Whitwell
209a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   if (texObj->Name > 0) {
210a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      /* remove from hash table */
211a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      _mesa_HashRemove(ctx->Shared->TexObjects, texObj->Name);
212a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   }
213afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
214afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
2156dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
21685d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul * Copy texture object state from one texture object to another.
2176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
2186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param dest destination texture object.
2196dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param src source texture object.
22085d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul */
22185d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paulvoid
22285d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul_mesa_copy_texture_object( struct gl_texture_object *dest,
22385d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul                           const struct gl_texture_object *src )
22485d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul{
22585d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->Name = src->Name;
22685d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->Priority = src->Priority;
22785d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->BorderColor[0] = src->BorderColor[0];
22885d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->BorderColor[1] = src->BorderColor[1];
22985d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->BorderColor[2] = src->BorderColor[2];
23085d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->BorderColor[3] = src->BorderColor[3];
23185d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->WrapS = src->WrapS;
23285d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->WrapT = src->WrapT;
23385d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->WrapR = src->WrapR;
23485d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->MinFilter = src->MinFilter;
23585d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->MagFilter = src->MagFilter;
23685d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->MinLod = src->MinLod;
23785d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->MaxLod = src->MaxLod;
238781fb93877ea3a6faeefcdb48d9b463da7d954a3Brian Paul   dest->LodBias = src->LodBias;
23985d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->BaseLevel = src->BaseLevel;
24085d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->MaxLevel = src->MaxLevel;
24185d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->MaxAnisotropy = src->MaxAnisotropy;
24285d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->CompareFlag = src->CompareFlag;
24385d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->CompareOperator = src->CompareOperator;
24485d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->ShadowAmbient = src->ShadowAmbient;
24585d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->CompareMode = src->CompareMode;
24685d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->CompareFunc = src->CompareFunc;
24785d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->DepthMode = src->DepthMode;
24885d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->_MaxLevel = src->_MaxLevel;
24985d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->_MaxLambda = src->_MaxLambda;
25085d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->GenerateMipmap = src->GenerateMipmap;
25185d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->Palette = src->Palette;
25285d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->Complete = src->Complete;
253887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul   dest->_IsPowerOfTwo = src->_IsPowerOfTwo;
25485d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul}
25585d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul
25685d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul
2576dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
2586dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Report why a texture object is incomplete.
2596dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
2606dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param t texture object.
2616dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param why string describing why it's incomplete.
2626dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
2636dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \note For debug purposes only.
264a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul */
26521d073d55ad668494fa19977fe06369194eb1ec5Brian Paul#if 0
26621d073d55ad668494fa19977fe06369194eb1ec5Brian Paulstatic void
26721d073d55ad668494fa19977fe06369194eb1ec5Brian Paulincomplete(const struct gl_texture_object *t, const char *why)
26821d073d55ad668494fa19977fe06369194eb1ec5Brian Paul{
2694e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   _mesa_printf("Texture Obj %d incomplete because: %s\n", t->Name, why);
27021d073d55ad668494fa19977fe06369194eb1ec5Brian Paul}
27121d073d55ad668494fa19977fe06369194eb1ec5Brian Paul#else
2726dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell#define incomplete(t, why)
27321d073d55ad668494fa19977fe06369194eb1ec5Brian Paul#endif
274afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
275afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
2766dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
277a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul * Examine a texture object to determine if it is complete.
2786dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
2796dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE
2806dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * accordingly.
2816dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
2826dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param ctx GL context.
2836dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param t texture object.
2846dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
2856dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * According to the texture target, verifies that each of the mipmaps is
2866dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * present and has the expected size.
287afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
28835d5301a54153930ee6fd60dff1010ce9f901397Brian Paulvoid
28935d5301a54153930ee6fd60dff1010ce9f901397Brian Paul_mesa_test_texobj_completeness( const GLcontext *ctx,
29035d5301a54153930ee6fd60dff1010ce9f901397Brian Paul                                struct gl_texture_object *t )
291afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
29263ec4238236479a57420c6b43a09d79eff624928Brian Paul   const GLint baseLevel = t->BaseLevel;
293cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   GLint maxLog2 = 0, maxLevels = 0;
29463ec4238236479a57420c6b43a09d79eff624928Brian Paul
295afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   t->Complete = GL_TRUE;  /* be optimistic */
296887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul   t->_IsPowerOfTwo = GL_TRUE;  /* may be set FALSE below */
297afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
298a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul   /* Always need the base level image */
29918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   if (!t->Image[0][baseLevel]) {
3007e86eb991b50e0f52e6a0404289ca73126da6414Brian Paul      char s[100];
3014ccbe9e666b55b97e6482e0655277c33e434ff32Brian Paul      sprintf(s, "obj %p (%d) Image[baseLevel=%d] == NULL",
3024ccbe9e666b55b97e6482e0655277c33e434ff32Brian Paul              (void *) t, t->Name, baseLevel);
3037e86eb991b50e0f52e6a0404289ca73126da6414Brian Paul      incomplete(t, s);
304afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      t->Complete = GL_FALSE;
305afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
306afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
307afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
308973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul   /* Check width/height/depth for zero */
30918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   if (t->Image[0][baseLevel]->Width == 0 ||
31018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell       t->Image[0][baseLevel]->Height == 0 ||
31118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell       t->Image[0][baseLevel]->Depth == 0) {
312973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul      incomplete(t, "texture width = 0");
313973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul      t->Complete = GL_FALSE;
314973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul      return;
315973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul   }
316973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul
317083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul   /* Compute _MaxLevel */
3188afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   if (t->Target == GL_TEXTURE_1D) {
31918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      maxLog2 = t->Image[0][baseLevel]->WidthLog2;
320cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      maxLevels = ctx->Const.MaxTextureLevels;
321afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
3228afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   else if (t->Target == GL_TEXTURE_2D) {
32318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,
32418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                     t->Image[0][baseLevel]->HeightLog2);
3258afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLevels = ctx->Const.MaxTextureLevels;
326afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
3278afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   else if (t->Target == GL_TEXTURE_3D) {
32818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      GLint max = MAX2(t->Image[0][baseLevel]->WidthLog2,
32918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                       t->Image[0][baseLevel]->HeightLog2);
33018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      maxLog2 = MAX2(max, (GLint)(t->Image[0][baseLevel]->DepthLog2));
331cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      maxLevels = ctx->Const.Max3DTextureLevels;
332afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
3338afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
33418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,
33518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                     t->Image[0][baseLevel]->HeightLog2);
3368afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLevels = ctx->Const.MaxCubeTextureLevels;
3378afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   }
3388afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
3398afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLog2 = 0;  /* not applicable */
3408afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLevels = 1;  /* no mipmapping */
3418afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   }
342cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   else {
3438afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness");
344cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      return;
345cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   }
346cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul
347cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   ASSERT(maxLevels > 0);
348afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
349083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul   t->_MaxLevel = baseLevel + maxLog2;
350083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul   t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel);
351cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1);
352afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
353083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul   /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */
354083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul   t->_MaxLambda = (GLfloat) (t->_MaxLevel - t->BaseLevel);
355afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
3568afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
357a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      /* make sure that all six cube map level 0 images are the same size */
35818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      const GLuint w = t->Image[0][baseLevel]->Width2;
35918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      const GLuint h = t->Image[0][baseLevel]->Height2;
36018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      GLuint face;
36118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      for (face = 1; face < 6; face++) {
36218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	 if (t->Image[face][baseLevel] == NULL ||
36318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	     t->Image[face][baseLevel]->Width2 != w ||
36418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	     t->Image[face][baseLevel]->Height2 != h) {
36518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	    t->Complete = GL_FALSE;
36618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	    incomplete(t, "Non-quare cubemap image");
36718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	    return;
36818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	 }
369ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul      }
370ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul   }
371ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul
372887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul   /* check for non power of two */
37318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   if (!t->Image[0][baseLevel]->_IsPowerOfTwo) {
374887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul      t->_IsPowerOfTwo = GL_FALSE;
375887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul   }
376887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul
377887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul   /* extra checking for mipmaps */
378ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul   if (t->MinFilter != GL_NEAREST && t->MinFilter != GL_LINEAR) {
379afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /*
380afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg       * Mipmapping: determine if we have a complete set of mipmaps
381afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg       */
382afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLint i;
38363ec4238236479a57420c6b43a09d79eff624928Brian Paul      GLint minLevel = baseLevel;
384083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul      GLint maxLevel = t->_MaxLevel;
385afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
386afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (minLevel > maxLevel) {
387afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         t->Complete = GL_FALSE;
38821d073d55ad668494fa19977fe06369194eb1ec5Brian Paul         incomplete(t, "minLevel > maxLevel");
389afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         return;
390afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
391afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
392afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* Test dimension-independent attributes */
393afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      for (i = minLevel; i <= maxLevel; i++) {
39418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         if (t->Image[0][i]) {
39518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell            if (t->Image[0][i]->TexFormat != t->Image[0][baseLevel]->TexFormat) {
396afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               t->Complete = GL_FALSE;
39721d073d55ad668494fa19977fe06369194eb1ec5Brian Paul               incomplete(t, "Format[i] != Format[baseLevel]");
398afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;
399afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
40018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell            if (t->Image[0][i]->Border != t->Image[0][baseLevel]->Border) {
401afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               t->Complete = GL_FALSE;
40221d073d55ad668494fa19977fe06369194eb1ec5Brian Paul               incomplete(t, "Border[i] != Border[baseLevel]");
403afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;
404afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
405afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
406afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
407afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
408afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* Test things which depend on number of texture image dimensions */
4098afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      if (t->Target == GL_TEXTURE_1D) {
410afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* Test 1-D mipmaps */
41118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint width = t->Image[0][baseLevel]->Width2;
412cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul         for (i = baseLevel + 1; i < maxLevels; i++) {
413ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width > 1) {
414afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               width /= 2;
415afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
416afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (i >= minLevel && i <= maxLevel) {
41718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               if (!t->Image[0][i]) {
418afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
41918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                  incomplete(t, "1D Image[0][i] == NULL");
420afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
421afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
42218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               if (t->Image[0][i]->Width2 != width ) {
423afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
42418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                  incomplete(t, "1D Image[0][i] bad width");
425afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
426afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
427afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
428ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width == 1) {
429afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;  /* found smallest needed mipmap, all done! */
430afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
431afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
432afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
4338afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      else if (t->Target == GL_TEXTURE_2D) {
434afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* Test 2-D mipmaps */
43518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint width = t->Image[0][baseLevel]->Width2;
43618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint height = t->Image[0][baseLevel]->Height2;
437cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul         for (i = baseLevel + 1; i < maxLevels; i++) {
438ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width > 1) {
439afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               width /= 2;
440afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
441ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (height > 1) {
442afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               height /= 2;
443afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
444afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (i >= minLevel && i <= maxLevel) {
44518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               if (!t->Image[0][i]) {
446afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
44718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                  incomplete(t, "2D Image[0][i] == NULL");
448afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
449afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
45018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               if (t->Image[0][i]->Width2 != width) {
451afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
45218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                  incomplete(t, "2D Image[0][i] bad width");
453afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
454afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
45518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               if (t->Image[0][i]->Height2 != height) {
456afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
45718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                  incomplete(t, "2D Image[0][i] bad height");
458afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
459afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
460afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (width==1 && height==1) {
461afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;  /* found smallest needed mipmap, all done! */
462afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
463afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
464afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
465afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
4668afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      else if (t->Target == GL_TEXTURE_3D) {
467afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* Test 3-D mipmaps */
46818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint width = t->Image[0][baseLevel]->Width2;
46918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint height = t->Image[0][baseLevel]->Height2;
47018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint depth = t->Image[0][baseLevel]->Depth2;
471cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul	 for (i = baseLevel + 1; i < maxLevels; i++) {
472ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width > 1) {
473afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               width /= 2;
474afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
475ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (height > 1) {
476afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               height /= 2;
477afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
478ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (depth > 1) {
479afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               depth /= 2;
480afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
481afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (i >= minLevel && i <= maxLevel) {
48218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               if (!t->Image[0][i]) {
48318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                  incomplete(t, "3D Image[0][i] == NULL");
484afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
485afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
486afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
48718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               if (t->Image[0][i]->Format == GL_DEPTH_COMPONENT) {
4884182cf60d96a077a66675e89694529b5f9e4b329Brian Paul                  t->Complete = GL_FALSE;
4894182cf60d96a077a66675e89694529b5f9e4b329Brian Paul                  incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
4904182cf60d96a077a66675e89694529b5f9e4b329Brian Paul                  return;
4914182cf60d96a077a66675e89694529b5f9e4b329Brian Paul               }
49218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               if (t->Image[0][i]->Width2 != width) {
493afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
49418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                  incomplete(t, "3D Image[0][i] bad width");
495afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
496afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
49718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               if (t->Image[0][i]->Height2 != height) {
498afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
49918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                  incomplete(t, "3D Image[0][i] bad height");
500afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
501afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
50218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell               if (t->Image[0][i]->Depth2 != depth) {
503afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
50418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                  incomplete(t, "3D Image[0][i] bad depth");
505afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
506afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
507afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
508ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width == 1 && height == 1 && depth == 1) {
509afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;  /* found smallest needed mipmap, all done! */
510afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
511afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
512afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
5138afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
514ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul         /* make sure 6 cube faces are consistant */
51518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint width = t->Image[0][baseLevel]->Width2;
51618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint height = t->Image[0][baseLevel]->Height2;
517cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul	 for (i = baseLevel + 1; i < maxLevels; i++) {
518ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width > 1) {
519ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul               width /= 2;
520ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            }
521ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (height > 1) {
522ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul               height /= 2;
523ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            }
524ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (i >= minLevel && i <= maxLevel) {
52518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	       GLuint face;
52618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	       for (face = 0; face < 6; face++) {
52718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  /* check that we have images defined */
52818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  if (!t->Image[face][i]) {
52918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     t->Complete = GL_FALSE;
53018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     incomplete(t, "CubeMap Image[n][i] == NULL");
53118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     return;
53218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  }
53318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  /* Don't support GL_DEPTH_COMPONENT for cube maps */
53418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  if (t->Image[face][i]->Format == GL_DEPTH_COMPONENT) {
53518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     t->Complete = GL_FALSE;
53618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
53718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     return;
53818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  }
53918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  /* check that all six images have same size */
54018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  if (t->Image[face][i]->Width2!=width ||
54118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		      t->Image[face][i]->Height2!=height) {
54218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     t->Complete = GL_FALSE;
54318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     incomplete(t, "CubeMap Image[n][i] bad size");
54418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     return;
54518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  }
54618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	       }
54718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	    }
54818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	    if (width == 1 && height == 1) {
54918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	       return;  /* found smallest needed mipmap, all done! */
550ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            }
551ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul         }
552413d6a21f849a689b5c83ea04395856b44fc65a8Brian Paul      }
5538afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
5548afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         /* XXX special checking? */
5558afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      }
556afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      else {
5578afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         /* Target = ??? */
55808836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_problem(ctx, "Bug in gl_test_texture_object_completeness\n");
559afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
560afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
561afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
562afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
5636dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@}*/
564afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
565832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
5666dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/***********************************************************************/
5676dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** \name API functions */
5686dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@{*/
569afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
5706dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
5716dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Texture name generation lock.
5726dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
5736dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Used by _mesa_GenTextures() to guarantee that the generation and allocation
5746dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * of texture IDs is atomic.
575afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
5766dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell_glthread_DECLARE_STATIC_MUTEX(GenTexturesLock);
5776dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
5786dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
5796dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Generate texture names.
5806dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
5816dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of texture names to be generated.
582a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * \param textures an array in which will hold the generated texture names.
5836dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
5846dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glGenTextures().
5856dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
5866dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * While holding the GenTexturesLock lock, calls _mesa_HashFindFreeKeyBlock()
587a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * to find a block of free texture IDs which are stored in \p textures.
5886dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Corresponding empty texture objects are also generated.
5896dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell */
590c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
591a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul_mesa_GenTextures( GLsizei n, GLuint *textures )
592afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
593fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
594afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLuint first;
595afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
596cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END(ctx);
597afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
598507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul   if (n < 0) {
59908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
600afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
601afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
602afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
603a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul   if (!textures)
604507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return;
605832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
606832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul   /*
607832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul    * This must be atomic (generation and allocation of texture IDs)
608832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul    */
609832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul   _glthread_LOCK_MUTEX(GenTexturesLock);
610832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
611bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);
612afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
613afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Allocate new, empty texture objects */
614a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   for (i = 0; i < n; i++) {
615a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      struct gl_texture_object *texObj;
616afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLuint name = first + i;
6178afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      GLenum target = 0;
618a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      texObj = (*ctx->Driver.NewTextureObject)( ctx, name, target);
619a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      if (!texObj) {
620a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
621a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
622a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      }
623a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      _mesa_save_texture_object(ctx, texObj);
624a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul      textures[i] = name;
625afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
626832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
627832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul   _glthread_UNLOCK_MUTEX(GenTexturesLock);
628afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
629afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
630a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul
6316dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
6326dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Delete named textures.
6336dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
6346dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of textures to be deleted.
635a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * \param textures array of texture IDs to be deleted.
6366dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
6376dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glDeleteTextures().
6386dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
639a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * If we're about to delete a texture that's currently bound to any
640a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * texture unit, unbind the texture first.  Decrement the reference
641a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * count on the texture object and delete it if it's zero.
642a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * Recall that texture objects can be shared among several rendering
643a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * contexts.
644afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
645c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
646a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul_mesa_DeleteTextures( GLsizei n, const GLuint *textures)
647afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
648fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
649afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
650cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */
651afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
652a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul   if (!textures)
653507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return;
654507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul
655a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul   for (i = 0; i < n; i++) {
656a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul      if (textures[i] > 0) {
657a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         struct gl_texture_object *delObj = (struct gl_texture_object *)
658a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul            _mesa_HashLookup(ctx->Shared->TexObjects, textures[i]);
659a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         if (delObj) {
66059d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul            /* First check if this texture is currently bound.
66159d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul             * If so, unbind it and decrement the reference count.
66259d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul             */
663afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            GLuint u;
664610d59981a9f43fefe29b34ef19c184d28e2bef5Brian Paul            for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
665afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
666a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul               if (delObj == unit->Current1D) {
667a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul                  unit->Current1D = ctx->Shared->Default1D;
668a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul                  ctx->Shared->Default1D->RefCount++;
669cf462086246692282a4b51db4412bfb89f9c8c9bBrian Paul                  delObj->RefCount--;
670dae1774e206188d951332d2285ea9cf8796d1a64Brian Paul                  if (delObj == unit->_Current)
671dae1774e206188d951332d2285ea9cf8796d1a64Brian Paul                     unit->_Current = unit->Current1D;
672a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul               }
673a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul               else if (delObj == unit->Current2D) {
674a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul                  unit->Current2D = ctx->Shared->Default2D;
675a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul                  ctx->Shared->Default2D->RefCount++;
676cf462086246692282a4b51db4412bfb89f9c8c9bBrian Paul                  delObj->RefCount--;
677dae1774e206188d951332d2285ea9cf8796d1a64Brian Paul                  if (delObj == unit->_Current)
678dae1774e206188d951332d2285ea9cf8796d1a64Brian Paul                     unit->_Current = unit->Current2D;
679a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul               }
680a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul               else if (delObj == unit->Current3D) {
681a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul                  unit->Current3D = ctx->Shared->Default3D;
682a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul                  ctx->Shared->Default3D->RefCount++;
683cf462086246692282a4b51db4412bfb89f9c8c9bBrian Paul                  delObj->RefCount--;
684dae1774e206188d951332d2285ea9cf8796d1a64Brian Paul                  if (delObj == unit->_Current)
685dae1774e206188d951332d2285ea9cf8796d1a64Brian Paul                     unit->_Current = unit->Current3D;
686a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul               }
687a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul               else if (delObj == unit->CurrentCubeMap) {
688a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul                  unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
689a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul                  ctx->Shared->DefaultCubeMap->RefCount++;
690cf462086246692282a4b51db4412bfb89f9c8c9bBrian Paul                  delObj->RefCount--;
691dae1774e206188d951332d2285ea9cf8796d1a64Brian Paul                  if (delObj == unit->_Current)
692dae1774e206188d951332d2285ea9cf8796d1a64Brian Paul                     unit->_Current = unit->CurrentCubeMap;
693a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul               }
694e6962b183db6af2ed9d14b8b46eeaa42fde68b56Brian Paul               else if (delObj == unit->CurrentRect) {
695e6962b183db6af2ed9d14b8b46eeaa42fde68b56Brian Paul                  unit->CurrentRect = ctx->Shared->DefaultRect;
696e6962b183db6af2ed9d14b8b46eeaa42fde68b56Brian Paul                  ctx->Shared->DefaultRect->RefCount++;
697cf462086246692282a4b51db4412bfb89f9c8c9bBrian Paul                  delObj->RefCount--;
698e6962b183db6af2ed9d14b8b46eeaa42fde68b56Brian Paul                  if (delObj == unit->_Current)
699e6962b183db6af2ed9d14b8b46eeaa42fde68b56Brian Paul                     unit->_Current = unit->CurrentRect;
700e6962b183db6af2ed9d14b8b46eeaa42fde68b56Brian Paul               }
701afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
702a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            ctx->NewState |= _NEW_TEXTURE;
703afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
704f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul            /* If user hasn't already tried to delete the texture... */
705f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul            if (!delObj->DeletePending) {
706f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul               delObj->DeletePending = GL_TRUE;
707f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul               delObj->RefCount--;
708f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul               ASSERT(delObj->RefCount >= 0);
709f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul            }
7105a2f32b102ab862fb10ba6b89e0b68a71552c674Brian Paul
711f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul            /* See if we can really delete the texture now */
712a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            if (delObj->RefCount == 0) {
713f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul               ASSERT(delObj->Name != 0); /* Never delete default tex objects */
714a3f137094cd965d27e1b088499dd609b81a91906Brian Paul               _mesa_remove_texture_object(ctx, delObj);
715a3f137094cd965d27e1b088499dd609b81a91906Brian Paul               ASSERT(ctx->Driver.DeleteTexture);
716a3f137094cd965d27e1b088499dd609b81a91906Brian Paul               (*ctx->Driver.DeleteTexture)(ctx, delObj);
717afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
718afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
719afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
720afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
721afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
722afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
723f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul
7246dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
7256dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Bind a named texture to a texturing target.
7266dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
7276dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param target texture target.
7286dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texName texture name.
7296dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
7306dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glBindTexture().
7316dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
7326dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Determines the old texture object bound and returns immediately if rebinding
7336dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * the same texture.  Get the current texture which is either a default texture
7346dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * if name is null, a named texture from the hash, or a new texture if the
7356dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * given texture name is new. Increments its reference count, binds it, and
7366dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * calls dd_function_table::BindTexture. Decrements the old texture reference
7376dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * count and deletes it if it reaches zero.
738afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
739c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
740fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_BindTexture( GLenum target, GLuint texName )
741afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
742fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
743afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLuint unit = ctx->Texture.CurrentUnit;
744afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
745afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   struct gl_texture_object *oldTexObj;
7465c1e7fa6ee72f4403d9ec9d12830dd689b966e71Keith Whitwell   struct gl_texture_object *newTexObj = 0;
747cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END(ctx);
748afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
749afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
7504753d60dd070bb08d0116076bcc08025c86ce857Brian Paul      _mesa_debug(ctx, "glBindTexture %s %d\n",
751d09a1d8b29ae5841ae39b5c24c3f4693dd750559Brian Paul                  _mesa_lookup_enum_by_nr(target), (GLint) texName);
752afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
753f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul   /*
754f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul    * Get pointer to currently bound texture object (oldTexObj)
755f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul    */
756420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul   switch (target) {
757420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul      case GL_TEXTURE_1D:
758a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         oldTexObj = texUnit->Current1D;
759420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         break;
760420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul      case GL_TEXTURE_2D:
761a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         oldTexObj = texUnit->Current2D;
762420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         break;
763420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul      case GL_TEXTURE_3D:
764a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         oldTexObj = texUnit->Current3D;
765420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         break;
766fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul      case GL_TEXTURE_CUBE_MAP_ARB:
7678afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         if (!ctx->Extensions.ARB_texture_cube_map) {
7688afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
7698afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            return;
7708afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         }
7718afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         oldTexObj = texUnit->CurrentCubeMap;
7728afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         break;
7738afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      case GL_TEXTURE_RECTANGLE_NV:
7748afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         if (!ctx->Extensions.NV_texture_rectangle) {
7758afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
7768afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            return;
777fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul         }
7788afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         oldTexObj = texUnit->CurrentRect;
7798afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         break;
780420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul      default:
78108836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
782420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         return;
783afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
784afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
785afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (oldTexObj->Name == texName)
7867e0c5888eaf72483319533a805ce491e2ea7de92Brian Paul      /* XXX this might be wrong.  If the texobj is in use by another
7877e0c5888eaf72483319533a805ce491e2ea7de92Brian Paul       * context and a texobj parameter was changed, this might be our
7887e0c5888eaf72483319533a805ce491e2ea7de92Brian Paul       * only chance to update this context's hardware state.
7897e0c5888eaf72483319533a805ce491e2ea7de92Brian Paul       */
790a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      return;   /* rebinding the same texture- no change */
791afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
792a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul   /*
793a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul    * Get pointer to new texture object (newTexObj)
794a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul    */
795fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul   if (texName == 0) {
796a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      /* newTexObj = a default texture object */
797a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      switch (target) {
798a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         case GL_TEXTURE_1D:
799a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            newTexObj = ctx->Shared->Default1D;
800a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            break;
801a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         case GL_TEXTURE_2D:
802a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            newTexObj = ctx->Shared->Default2D;
803a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            break;
804a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         case GL_TEXTURE_3D:
805a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            newTexObj = ctx->Shared->Default3D;
806a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            break;
807a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         case GL_TEXTURE_CUBE_MAP_ARB:
808a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            newTexObj = ctx->Shared->DefaultCubeMap;
809a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            break;
8108afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         case GL_TEXTURE_RECTANGLE_NV:
8118afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            newTexObj = ctx->Shared->DefaultRect;
8128afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            break;
813a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         default:
814a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            ; /* Bad targets are caught above */
815a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      }
816fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul   }
817afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   else {
818a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      /* non-default texture object */
819a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      const struct _mesa_HashTable *hash = ctx->Shared->TexObjects;
820c79fab4aa6d4c2d399c2ca888fdf0e6c310f7303Brian Paul      newTexObj = (struct gl_texture_object *) _mesa_HashLookup(hash, texName);
821a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      if (newTexObj) {
822a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         /* error checking */
8238afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         if (newTexObj->Target != 0 && newTexObj->Target != target) {
824420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul            /* the named texture object's dimensions don't match the target */
8255a2f32b102ab862fb10ba6b89e0b68a71552c674Brian Paul            _mesa_error( ctx, GL_INVALID_OPERATION,
8265a2f32b102ab862fb10ba6b89e0b68a71552c674Brian Paul                         "glBindTexture(wrong dimensionality)" );
827a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            return;
828a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         }
8298afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         if (newTexObj->Target == 0 && target == GL_TEXTURE_RECTANGLE_NV) {
8308afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            /* have to init wrap and filter state here - kind of klunky */
8318afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            newTexObj->WrapS = GL_CLAMP_TO_EDGE;
8328afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            newTexObj->WrapT = GL_CLAMP_TO_EDGE;
8338afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            newTexObj->WrapR = GL_CLAMP_TO_EDGE;
8348afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul            newTexObj->MinFilter = GL_LINEAR;
835c71ee917e325e8b8c1591047d6e33adb4e051da8Roland Scheidegger            if (ctx->Driver.TexParameter) {
836c71ee917e325e8b8c1591047d6e33adb4e051da8Roland Scheidegger               static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
837c71ee917e325e8b8c1591047d6e33adb4e051da8Roland Scheidegger               static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
838c71ee917e325e8b8c1591047d6e33adb4e051da8Roland Scheidegger               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_S, fparam_wrap );
839c71ee917e325e8b8c1591047d6e33adb4e051da8Roland Scheidegger               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_T, fparam_wrap );
840c71ee917e325e8b8c1591047d6e33adb4e051da8Roland Scheidegger               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_R, fparam_wrap );
841c71ee917e325e8b8c1591047d6e33adb4e051da8Roland Scheidegger               (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_MIN_FILTER, fparam_filter );
842c71ee917e325e8b8c1591047d6e33adb4e051da8Roland Scheidegger            }
8438afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         }
844afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
845a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      else {
846a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         /* if this is a new texture id, allocate a texture object now */
847a3f137094cd965d27e1b088499dd609b81a91906Brian Paul	 newTexObj = (*ctx->Driver.NewTextureObject)(ctx, texName, target);
848a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         if (!newTexObj) {
84908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
850a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            return;
851a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         }
852a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_save_texture_object(ctx, newTexObj);
853a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      }
8548afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      newTexObj->Target = target;
855afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
856afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
857afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   newTexObj->RefCount++;
8586e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul
859cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   /* do the actual binding, but first flush outstanding vertices:
860cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell    */
861cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
862cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
863fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul   switch (target) {
864fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul      case GL_TEXTURE_1D:
865a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         texUnit->Current1D = newTexObj;
866fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul         break;
867fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul      case GL_TEXTURE_2D:
868a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         texUnit->Current2D = newTexObj;
869fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul         break;
870fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul      case GL_TEXTURE_3D:
871a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         texUnit->Current3D = newTexObj;
872fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul         break;
873fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul      case GL_TEXTURE_CUBE_MAP_ARB:
874fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul         texUnit->CurrentCubeMap = newTexObj;
875fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul         break;
8768afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      case GL_TEXTURE_RECTANGLE_NV:
8778afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         texUnit->CurrentRect = newTexObj;
8788afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         break;
879fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul      default:
88008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_problem(ctx, "bad target in BindTexture");
8818afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         return;
882fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul   }
883afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
884afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Pass BindTexture call to device driver */
8855e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen   if (ctx->Driver.BindTexture)
886afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      (*ctx->Driver.BindTexture)( ctx, target, newTexObj );
8876e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul
888f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul   /* Decrement the reference count on the old texture and check if it's
889f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul    * time to delete it.
890f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul    */
8915a2f32b102ab862fb10ba6b89e0b68a71552c674Brian Paul   oldTexObj->RefCount--;
892f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul   ASSERT(oldTexObj->RefCount >= 0);
8935a2f32b102ab862fb10ba6b89e0b68a71552c674Brian Paul   if (oldTexObj->RefCount == 0) {
894f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul      ASSERT(oldTexObj->Name != 0);
895f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul      ASSERT(oldTexObj->DeletePending);
896a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      _mesa_remove_texture_object(ctx, oldTexObj);
897a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      ASSERT(ctx->Driver.DeleteTexture);
898a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
8996e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul   }
900afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
901afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
902f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul
9036dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
9046dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Set texture priorities.
9056dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9066dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of textures.
9076dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texName texture names.
9086dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param priorities corresponding texture priorities.
9096dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9106dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glPrioritizeTextures().
9116dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9126dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Looks up each texture in the hash, clamps the corresponding priority between
9136dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture.
914afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
915c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
916fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,
917fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul                          const GLclampf *priorities )
918afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
919fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
920afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
921cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
922afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
9236d04725282f32cbd32acbc8b79294a2a056b2158Brian Paul   if (n < 0) {
92408836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" );
925afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
926afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
927afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
928507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul   if (!priorities)
929507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return;
930507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul
9316d04725282f32cbd32acbc8b79294a2a056b2158Brian Paul   for (i = 0; i < n; i++) {
9326d04725282f32cbd32acbc8b79294a2a056b2158Brian Paul      if (texName[i] > 0) {
9336d04725282f32cbd32acbc8b79294a2a056b2158Brian Paul         struct gl_texture_object *t = (struct gl_texture_object *)
934bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul            _mesa_HashLookup(ctx->Shared->TexObjects, texName[i]);
935afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         if (t) {
936afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );
93769cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell	    if (ctx->Driver.PrioritizeTexture)
93869cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell	       ctx->Driver.PrioritizeTexture( ctx, t, t->Priority );
939afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
940afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
941afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
942a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell
943a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell   ctx->NewState |= _NEW_TEXTURE;
944afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
945afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
9466dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
9476dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * See if textures are loaded in texture memory.
9486dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9496dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of textures to query.
9506dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texName array with the texture names.
9516dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param residences array which will hold the residence status.
9526dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9536dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \return GL_TRUE if all textures are resident and \p residences is left unchanged,
9546dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9556dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glAreTexturesResident().
9566dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9576dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Looks up each texture in the hash and calls
9586dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * dd_function_table::IsTextureResident.
959afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
960c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall BennettGLboolean GLAPIENTRY
961bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul_mesa_AreTexturesResident(GLsizei n, const GLuint *texName,
962bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul                          GLboolean *residences)
963afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
964fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
965bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   GLboolean allResident = GL_TRUE;
96624e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul   GLint i, j;
967cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
968afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
969bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   if (n < 0) {
97008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)");
971afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return GL_FALSE;
972afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
973afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
974507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul   if (!texName || !residences)
975507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return GL_FALSE;
976507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul
977bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   for (i = 0; i < n; i++) {
978afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      struct gl_texture_object *t;
979bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul      if (texName[i] == 0) {
98024e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
981afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         return GL_FALSE;
982afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
983afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      t = (struct gl_texture_object *)
984bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul         _mesa_HashLookup(ctx->Shared->TexObjects, texName[i]);
98524e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul      if (!t) {
98624e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
98724e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         return GL_FALSE;
98824e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul      }
98924e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul      if (!ctx->Driver.IsTextureResident ||
99024e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul          ctx->Driver.IsTextureResident(ctx, t)) {
99124e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         /* The texture is resident */
99224e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul	 if (!allResident)
99369cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell	    residences[i] = GL_TRUE;
994afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
995afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      else {
99624e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         /* The texture is not resident */
99724e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         if (allResident) {
99824e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul	    allResident = GL_FALSE;
99924e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul	    for (j = 0; j < i; j++)
100024e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul	       residences[j] = GL_TRUE;
100124e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul	 }
100224e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul	 residences[i] = GL_FALSE;
1003afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
1004afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
100524e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul
1006bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   return allResident;
1007afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
1008afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
10096dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
10106dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * See if a name corresponds to a texture.
10116dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
10126dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texture texture name.
10136dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
10146dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE
10156dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * otherwise.
10166dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
10176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glIsTexture().
10186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
10196dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Calls _mesa_HashLookup().
1020afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1021c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall BennettGLboolean GLAPIENTRY
1022fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_IsTexture( GLuint texture )
1023afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
10243ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   struct gl_texture_object *t;
1025fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1026cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
10273ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul
10283ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   if (!t)
10293ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul      return GL_FALSE;
10303ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul
10313ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   t = (struct gl_texture_object *)
10323ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul      _mesa_HashLookup(ctx->Shared->TexObjects, texture);
10333ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul
10343ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   /* IsTexture is true only after object has been bound once. */
10353ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   return t && t->Target;
1036afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
10376dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
10386dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@}*/
1039