texobj.c revision 832179c50e2cf5de9735241e4767aea4d6fc33bf
1832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul/* $Id: texobj.c,v 1.15 2000/03/21 17:42:27 brianp Exp $ */
2afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
3afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
4afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Mesa 3-D graphics library
5fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul * Version:  3.3
6afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *
7bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
8afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *
9afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Permission is hereby granted, free of charge, to any person obtaining a
10afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * copy of this software and associated documentation files (the "Software"),
11afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * to deal in the Software without restriction, including without limitation
12afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * and/or sell copies of the Software, and to permit persons to whom the
14afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Software is furnished to do so, subject to the following conditions:
15afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *
16afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * The above copyright notice and this permission notice shall be included
17afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * in all copies or substantial portions of the Software.
18afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *
19afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
26afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
27afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
28afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef PC_HEADER
29afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "all.h"
30afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#else
31fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul#include "glheader.h"
32afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "context.h"
33afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "enums.h"
34afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "hash.h"
35fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul#include "mem.h"
36afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "teximage.h"
37afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "texstate.h"
38afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "texobj.h"
39afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "types.h"
40afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif
41afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
42afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
43afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
44afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
45afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Allocate a new texture object and add it to the linked list of texture
46afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * objects.  If name>0 then also insert the new texture object into the hash
47afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * table.
48afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Input:  shared - the shared GL state structure to contain the texture object
49afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *         name - integer name for the texture object
50afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *         dimensions - either 1, 2 or 3
51afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Return:  pointer to new texture object
52afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
53afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstruct gl_texture_object *
54afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtggl_alloc_texture_object( struct gl_shared_state *shared, GLuint name,
55afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                         GLuint dimensions)
56afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
57afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   struct gl_texture_object *obj;
58afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
59420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul   ASSERT(dimensions <= 3);
60420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul
61420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul   obj = CALLOC_STRUCT(gl_texture_object);
62afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
63afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (obj) {
64afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* init the non-zero fields */
656e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul      obj->RefCount = 1;
66afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->Name = name;
67afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->Dimensions = dimensions;
68afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->WrapS = GL_REPEAT;
69afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->WrapT = GL_REPEAT;
70afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
71afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->MagFilter = GL_LINEAR;
72afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->MinLod = -1000.0;
73afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->MaxLod = 1000.0;
74afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->BaseLevel = 0;
75afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->MaxLevel = 1000;
76afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      obj->MinMagThresh = 0.0F;
77fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul      obj->Palette.Table[0] = 255;
78fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul      obj->Palette.Table[1] = 255;
79fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul      obj->Palette.Table[2] = 255;
80fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul      obj->Palette.Table[3] = 255;
81fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul      obj->Palette.Size = 1;
82fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul      obj->Palette.IntFormat = GL_RGBA;
83fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul      obj->Palette.Format = GL_RGBA;
84afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
85afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* insert into linked list */
86afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (shared) {
879560f05deffaf0321bba1bd0fcc8eeef4199e6e0Brian Paul         _glthread_LOCK_MUTEX(shared->Mutex);
88afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         obj->Next = shared->TexObjectList;
89afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         shared->TexObjectList = obj;
909560f05deffaf0321bba1bd0fcc8eeef4199e6e0Brian Paul         _glthread_UNLOCK_MUTEX(shared->Mutex);
91afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
92afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
93afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (name > 0) {
94afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* insert into hash table */
95bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul         _mesa_HashInsert(shared->TexObjects, name, obj);
96afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
97afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
98afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   return obj;
99afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
100afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
101afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
102afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
103afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Deallocate a texture object struct and remove it from the given
104afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * shared GL state.
105afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Input:  shared - the shared GL state to which the object belongs
106afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *         t - the texture object to delete
107afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
108afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgvoid gl_free_texture_object( struct gl_shared_state *shared,
109afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                             struct gl_texture_object *t )
110afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
111afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   struct gl_texture_object *tprev, *tcurr;
112afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
113afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   assert(t);
114afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
115afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Remove t from dirty list so we don't touch free'd memory later.
116afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg    * Test for shared since Proxy texture aren't in global linked list.
117afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg    */
118afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (shared)
119afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      gl_remove_texobj_from_dirty_list( shared, t );
120afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
121afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* unlink t from the linked list */
122afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (shared) {
1239560f05deffaf0321bba1bd0fcc8eeef4199e6e0Brian Paul      _glthread_LOCK_MUTEX(shared->Mutex);
124afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      tprev = NULL;
125afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      tcurr = shared->TexObjectList;
126afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      while (tcurr) {
127afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         if (tcurr==t) {
128afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (tprev) {
129afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               tprev->Next = t->Next;
130afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
131afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            else {
132afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               shared->TexObjectList = t->Next;
133afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
134afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            break;
135afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
136afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         tprev = tcurr;
137afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         tcurr = tcurr->Next;
138afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
1399560f05deffaf0321bba1bd0fcc8eeef4199e6e0Brian Paul      _glthread_UNLOCK_MUTEX(shared->Mutex);
140afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
141afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
142afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (t->Name) {
143afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* remove from hash table */
144bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul      _mesa_HashRemove(shared->TexObjects, t->Name);
145afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
146afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
147afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* free texture image */
148afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   {
149afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLuint i;
150afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      for (i=0;i<MAX_TEXTURE_LEVELS;i++) {
151afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         if (t->Image[i]) {
152afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            gl_free_texture_image( t->Image[i] );
153afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
154afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
155afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
156afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* free this object */
157bd5cdaf4442872d3cd2ff94eeafadd481d27fcfbBrian Paul   FREE( t );
158afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
159afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
160afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
161afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
162afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
163afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Examine a texture object to determine if it is complete or not.
164afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * The t->Complete flag will be set to GL_TRUE or GL_FALSE accordingly.
165afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
166afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgvoid gl_test_texture_object_completeness( const GLcontext *ctx, struct gl_texture_object *t )
167afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
168afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   t->Complete = GL_TRUE;  /* be optimistic */
169afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
170afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Always need level zero image */
171afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (!t->Image[0] || !t->Image[0]->Data) {
172afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      t->Complete = GL_FALSE;
173afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
174afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
175afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
176afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Compute number of mipmap levels */
177afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (t->Dimensions==1) {
178afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      t->P = t->Image[0]->WidthLog2;
179afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
180afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   else if (t->Dimensions==2) {
181afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      t->P = MAX2(t->Image[0]->WidthLog2, t->Image[0]->HeightLog2);
182afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
183afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   else if (t->Dimensions==3) {
184afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLint max = MAX2(t->Image[0]->WidthLog2, t->Image[0]->HeightLog2);
185afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      max = MAX2(max, (GLint)(t->Image[0]->DepthLog2));
186afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      t->P = max;
187afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
188afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
189afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Compute M (see the 1.2 spec) used during mipmapping */
190afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   t->M = (GLfloat) (MIN2(t->MaxLevel, t->P) - t->BaseLevel);
191afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
192afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
193afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (t->MinFilter!=GL_NEAREST && t->MinFilter!=GL_LINEAR) {
194afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /*
195afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg       * Mipmapping: determine if we have a complete set of mipmaps
196afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg       */
197afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLint i;
198afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLint minLevel = t->BaseLevel;
199afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLint maxLevel = MIN2(t->P, ctx->Const.MaxTextureLevels-1);
200afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      maxLevel = MIN2(maxLevel, t->MaxLevel);
201afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
202afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (minLevel > maxLevel) {
203afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         t->Complete = GL_FALSE;
204afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         return;
205afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
206afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
207afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* Test dimension-independent attributes */
208afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      for (i = minLevel; i <= maxLevel; i++) {
209afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         if (t->Image[i]) {
210afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (!t->Image[i]->Data) {
211afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               t->Complete = GL_FALSE;
212afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;
213afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
214afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (t->Image[i]->Format != t->Image[0]->Format) {
215afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               t->Complete = GL_FALSE;
216afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;
217afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
218afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (t->Image[i]->Border != t->Image[0]->Border) {
219afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               t->Complete = GL_FALSE;
220afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;
221afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
222afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
223afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
224afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
225afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* Test things which depend on number of texture image dimensions */
226afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (t->Dimensions==1) {
227afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* Test 1-D mipmaps */
228afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         GLuint width = t->Image[0]->Width2;
229afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         for (i=1; i<ctx->Const.MaxTextureLevels; i++) {
230afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (width>1) {
231afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               width /= 2;
232afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
233afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (i >= minLevel && i <= maxLevel) {
234afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (!t->Image[i]) {
235afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
236afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
237afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
238afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (!t->Image[i]->Data) {
239afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
240afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
241afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
242afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (t->Image[i]->Width2 != width ) {
243afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
244afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
245afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
246afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
247afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (width==1) {
248afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;  /* found smallest needed mipmap, all done! */
249afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
250afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
251afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
252afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      else if (t->Dimensions==2) {
253afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* Test 2-D mipmaps */
254afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         GLuint width = t->Image[0]->Width2;
255afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         GLuint height = t->Image[0]->Height2;
256afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         for (i=1; i<ctx->Const.MaxTextureLevels; i++) {
257afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (width>1) {
258afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               width /= 2;
259afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
260afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (height>1) {
261afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               height /= 2;
262afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
263afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (i >= minLevel && i <= maxLevel) {
264afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (!t->Image[i]) {
265afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
266afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
267afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
268afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (t->Image[i]->Width2 != width) {
269afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
270afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
271afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
272afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (t->Image[i]->Height2 != height) {
273afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
274afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
275afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
276afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (width==1 && height==1) {
277afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;  /* found smallest needed mipmap, all done! */
278afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
279afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
280afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
281afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
282afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      else if (t->Dimensions==3) {
283afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* Test 3-D mipmaps */
284afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         GLuint width = t->Image[0]->Width2;
285afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         GLuint height = t->Image[0]->Height2;
286afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         GLuint depth = t->Image[0]->Depth2;
287afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	 for (i=1; i<ctx->Const.MaxTextureLevels; i++) {
288afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (width>1) {
289afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               width /= 2;
290afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
291afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (height>1) {
292afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               height /= 2;
293afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
294afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (depth>1) {
295afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               depth /= 2;
296afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
297afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (i >= minLevel && i <= maxLevel) {
298afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (!t->Image[i]) {
299afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
300afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
301afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
302afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (t->Image[i]->Width2 != width) {
303afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
304afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
305afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
306afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (t->Image[i]->Height2 != height) {
307afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
308afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
309afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
310afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (t->Image[i]->Depth2 != depth) {
311afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  t->Complete = GL_FALSE;
312afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
313afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
314afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
315afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (width==1 && height==1 && depth==1) {
316afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;  /* found smallest needed mipmap, all done! */
317afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
318afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
319afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
320afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      else {
321afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* Dimensions = ??? */
322afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         gl_problem(NULL, "Bug in gl_test_texture_object_completeness\n");
323afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
324afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
325afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
326afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
327afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
328832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul_glthread_DECLARE_STATIC_MUTEX(GenTexturesLock);
329832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
330afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
331afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
332afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Execute glGenTextures
333afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
334fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paulvoid
335fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_GenTextures( GLsizei n, GLuint *texName )
336afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
337fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
338afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLuint first;
339afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
340afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
341afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGenTextures");
342afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (n<0) {
343afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      gl_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
344afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
345afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
346afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
347832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
348832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul   /*
349832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul    * This must be atomic (generation and allocation of texture IDs)
350832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul    */
351832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul   _glthread_LOCK_MUTEX(GenTexturesLock);
352832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
353bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);
354afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
355afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Return the texture names */
356afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   for (i=0;i<n;i++) {
357afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      texName[i] = first + i;
358afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
359afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
360afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Allocate new, empty texture objects */
361afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   for (i=0;i<n;i++) {
362afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLuint name = first + i;
363afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLuint dims = 0;
364afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      (void) gl_alloc_texture_object(ctx->Shared, name, dims);
365afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
366832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
367832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul   _glthread_UNLOCK_MUTEX(GenTexturesLock);
368afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
369afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
370afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
371afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
372afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
373afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Execute glDeleteTextures
374afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
375fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paulvoid
376fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_DeleteTextures( GLsizei n, const GLuint *texName)
377afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
378fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
379afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
380afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
381afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDeleteTextures");
382afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
383afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   for (i=0;i<n;i++) {
384afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      struct gl_texture_object *t;
385afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (texName[i]>0) {
386afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         t = (struct gl_texture_object *)
387bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul            _mesa_HashLookup(ctx->Shared->TexObjects, texName[i]);
388afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         if (t) {
38959d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul            /* First check if this texture is currently bound.
39059d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul             * If so, unbind it and decrement the reference count.
39159d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul             */
392afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            GLuint u;
39359d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul            for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
394afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
395afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	       GLuint d;
396afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	       for (d = 1 ; d <= 3 ; d++) {
39759d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul		  if (unit->CurrentD[d] == t) {
3986e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul		     unit->CurrentD[d] = ctx->Shared->DefaultD[d];
3996e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul		     ctx->Shared->DefaultD[d]->RefCount++;
400afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		     t->RefCount--;
40159d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul		     ASSERT( t->RefCount >= 0 );
402afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg		  }
403afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	       }
404afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
405afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
40659d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul            /* Decrement reference count and delete if zero */
40759d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul            t->RefCount--;
40859d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul            ASSERT( t->RefCount >= 0 );
40959d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul            if (t->RefCount == 0) {
41059d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul               if (ctx->Driver.DeleteTexture)
41159d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul                  (*ctx->Driver.DeleteTexture)( ctx, t );
412afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               gl_free_texture_object(ctx->Shared, t);
413afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
414afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
415afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
416afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
417afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
418afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
419afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
420afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
421afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
422afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Execute glBindTexture
423afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
424fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paulvoid
425fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_BindTexture( GLenum target, GLuint texName )
426afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
427fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
428afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLuint unit = ctx->Texture.CurrentUnit;
429afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
430afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   struct gl_texture_object *oldTexObj;
431afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   struct gl_texture_object *newTexObj;
4325b37c322741f019118a618bc6220f37adba4fbcdBrian Paul   GLuint dim;
433afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
434afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
435afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      fprintf(stderr, "glBindTexture %s %d\n",
436afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	      gl_lookup_enum_by_nr(target), (GLint) texName);
437afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
438afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glBindTexture");
439afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
440420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul   switch (target) {
441420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul      case GL_TEXTURE_1D:
442420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         dim = 1;
443420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         break;
444420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul      case GL_TEXTURE_2D:
445420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         dim = 2;
446420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         break;
447420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul      case GL_TEXTURE_3D:
448420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         dim = 3;
449420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         break;
450420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul      default:
451420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         gl_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
452420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul         return;
453afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
454afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
455afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   oldTexObj = texUnit->CurrentD[dim];
456afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
457afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (oldTexObj->Name == texName)
458afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
459afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
460afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (texName == 0)
4616e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul      newTexObj = ctx->Shared->DefaultD[dim];
462afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   else {
463bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul      struct _mesa_HashTable *hash = ctx->Shared->TexObjects;
464c79fab4aa6d4c2d399c2ca888fdf0e6c310f7303Brian Paul      newTexObj = (struct gl_texture_object *) _mesa_HashLookup(hash, texName);
465afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
466afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (!newTexObj)
467afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	 newTexObj = gl_alloc_texture_object(ctx->Shared, texName, dim);
468afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
469afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (newTexObj->Dimensions != dim) {
470afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	 if (newTexObj->Dimensions) {
471420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul            /* the named texture object's dimensions don't match the target */
472afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	    gl_error( ctx, GL_INVALID_OPERATION, "glBindTexture" );
473afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	    return;
474afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	 }
475afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	 newTexObj->Dimensions = dim;
476afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
477afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
478afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
479afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   newTexObj->RefCount++;
4806e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul
481afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   texUnit->CurrentD[dim] = newTexObj;
482afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
483afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* If we've changed the CurrentD[123] texture object then update the
484afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg    * ctx->Texture.Current pointer to point to the new texture object.
485afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg    */
486afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   texUnit->Current = texUnit->CurrentD[texUnit->CurrentDimension];
487afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
488afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Check if we may have to use a new triangle rasterizer */
489afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if ((ctx->IndirectTriangles & DD_SW_RASTERIZE) &&
490afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg       (   oldTexObj->WrapS != newTexObj->WrapS
491afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        || oldTexObj->WrapT != newTexObj->WrapT
492afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        || oldTexObj->WrapR != newTexObj->WrapR
493afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        || oldTexObj->MinFilter != newTexObj->MinFilter
494afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        || oldTexObj->MagFilter != newTexObj->MagFilter
495afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg        || (oldTexObj->Image[0] && newTexObj->Image[0] &&
496afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg	   (oldTexObj->Image[0]->Format!=newTexObj->Image[0]->Format))))
497afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   {
498afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      ctx->NewState |= (NEW_RASTER_OPS | NEW_TEXTURING);
499afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
500afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
501afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (oldTexObj->Complete != newTexObj->Complete)
502afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      ctx->NewState |= NEW_TEXTURING;
503afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
504afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Pass BindTexture call to device driver */
505afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (ctx->Driver.BindTexture) {
506afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      (*ctx->Driver.BindTexture)( ctx, target, newTexObj );
507afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
5086e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul
5096e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul   if (oldTexObj->Name > 0) {
5106e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul      /* never delete default (id=0) texture objects */
5116e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul      oldTexObj->RefCount--;
5126e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul      if (oldTexObj->RefCount <= 0) {
5136e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul         if (ctx->Driver.DeleteTexture) {
5146e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul	    (*ctx->Driver.DeleteTexture)( ctx, oldTexObj );
5156e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul	 }
5166e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul         gl_free_texture_object(ctx->Shared, oldTexObj);
5176e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul      }
5186e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul   }
519afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
520afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
521afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
522afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
523afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
524afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Execute glPrioritizeTextures
525afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
526fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paulvoid
527fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,
528fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul                          const GLclampf *priorities )
529afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
530fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
531afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
532afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
533afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPrioritizeTextures");
534afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (n<0) {
535afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      gl_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" );
536afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
537afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
538afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
539afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   for (i=0;i<n;i++) {
540afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      struct gl_texture_object *t;
541afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (texName[i]>0) {
542afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         t = (struct gl_texture_object *)
543bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul            _mesa_HashLookup(ctx->Shared->TexObjects, texName[i]);
544afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         if (t) {
545afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );
54669cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell
54769cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell	    if (ctx->Driver.PrioritizeTexture)
54869cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell	       ctx->Driver.PrioritizeTexture( ctx, t, t->Priority );
549afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
550afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
551afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
552afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
553afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
554afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
555afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
556afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
55769cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell * Execute glAreTexturesResident
558afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
559fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian PaulGLboolean
560fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_AreTexturesResident( GLsizei n, const GLuint *texName,
561fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul                           GLboolean *residences )
562afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
563fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
564afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLboolean resident = GL_TRUE;
565afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
566afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
567afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx,
568afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg						  "glAreTexturesResident",
569afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg						  GL_FALSE);
570afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (n<0) {
571afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      gl_error( ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)" );
572afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return GL_FALSE;
573afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
574afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
575afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   for (i=0;i<n;i++) {
576afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      struct gl_texture_object *t;
577afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (texName[i]==0) {
578afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         gl_error( ctx, GL_INVALID_VALUE, "glAreTexturesResident(textures)" );
579afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         return GL_FALSE;
580afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
581afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      t = (struct gl_texture_object *)
582bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul         _mesa_HashLookup(ctx->Shared->TexObjects, texName[i]);
583afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (t) {
58469cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell	 if (ctx->Driver.IsTextureResident)
58569cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell	    residences[i] = ctx->Driver.IsTextureResident( ctx, t );
58669cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell	 else
58769cfdb2fcb6c6d5538aff6533b587a54fb2e74c3Keith Whitwell	    residences[i] = GL_TRUE;
588afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
589afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      else {
590afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         gl_error( ctx, GL_INVALID_VALUE, "glAreTexturesResident(textures)" );
591afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         return GL_FALSE;
592afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
593afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
594afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   return resident;
595afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
596afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
597afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
598afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
599afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
600afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Execute glIsTexture
601afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
602fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian PaulGLboolean
603fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_IsTexture( GLuint texture )
604afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
605fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
606afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, "glIsTextures",
607afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg						  GL_FALSE);
608bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul   if (texture>0 && _mesa_HashLookup(ctx->Shared->TexObjects, texture)) {
609afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return GL_TRUE;
610afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
611afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   else {
612afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return GL_FALSE;
613afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
614afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
615afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
616