texobj.c revision 4c9537f7d06af9f7f8a706ecd784ce3b04e132e8
16dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
26dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \file texobj.c
36dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Texture object management.
46dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell */
56dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
6afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
7afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Mesa 3-D graphics library
8145d762044f795bf9d68f28079cc5e5d3056920eBrian * Version:  7.1
95e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen *
10145d762044f795bf9d68f28079cc5e5d3056920eBrian * Copyright (C) 1999-2007  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
31f2c023291a1f2887294d2aac504f8b82857ad092Brian Paul#include "mfeatures.h"
32874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul#include "bufferobj.h"
334bdcfe50f8886e43714f9b7edd25cbff19e6a97dBrian Paul#include "colortab.h"
34afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "context.h"
35afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "enums.h"
36519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul#include "fbobject.h"
377ac233ec15743763996e59c8b283f7c2e78a7210Brian Paul#include "formats.h"
38afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "hash.h"
393c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h"
40ebb248aa5c018dc676d389221d76ed329059789eBrian Paul#include "macros.h"
41afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "teximage.h"
42afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#include "texobj.h"
43cbadedb511cfcebaf15029891221211219584fb3Brian Paul#include "texstate.h"
445e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen#include "mtypes.h"
45ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_instruction.h"
464a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul
47afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
48519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
496dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**********************************************************************/
506dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** \name Internal functions */
516dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@{*/
526dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
53ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul
54ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul/**
55ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul * Return the gl_texture_object for a given ID.
56ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul */
57ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paulstruct gl_texture_object *
58f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_lookup_texture(struct gl_context *ctx, GLuint id)
59ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul{
60ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   return (struct gl_texture_object *)
61ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      _mesa_HashLookup(ctx->Shared->TexObjects, id);
62ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul}
63ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul
64ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul
65ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul
66a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/**
678a033fa13514e3b78612ba1678182c9ea8290cd4Brian Paul * Allocate and initialize a new texture object.  But don't put it into the
688a033fa13514e3b78612ba1678182c9ea8290cd4Brian Paul * texture object hash table.
696dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
70a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * Called via ctx->Driver.NewTextureObject, unless overridden by a device
71a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * driver.
726dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
736dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param shared the shared GL state structure to contain the texture object
746dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param name integer name for the texture object
756dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
766dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV.  zero is ok for the sake
776dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * of GenTextures()
786dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
796dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \return pointer to new texture object.
80afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
81afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtgstruct gl_texture_object *
82f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_new_texture_object( struct gl_context *ctx, GLuint name, GLenum target )
83afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
84afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   struct gl_texture_object *obj;
85a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
869c0b83556dae35cf7260567f30fc156efa8c9742Brian Paul   obj = MALLOC_STRUCT(gl_texture_object);
87a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   _mesa_initialize_texture_object(obj, name, target);
88a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   return obj;
89a3f137094cd965d27e1b088499dd609b81a91906Brian Paul}
90afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
91a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
92a3f137094cd965d27e1b088499dd609b81a91906Brian Paul/**
93f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul * Initialize a new texture object to default values.
94a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * \param obj  the texture object
95a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * \param name  the texture name
96a3f137094cd965d27e1b088499dd609b81a91906Brian Paul * \param target  the texture target
97a3f137094cd965d27e1b088499dd609b81a91906Brian Paul */
98a3f137094cd965d27e1b088499dd609b81a91906Brian Paulvoid
99a3f137094cd965d27e1b088499dd609b81a91906Brian Paul_mesa_initialize_texture_object( struct gl_texture_object *obj,
100a3f137094cd965d27e1b088499dd609b81a91906Brian Paul                                 GLuint name, GLenum target )
101a3f137094cd965d27e1b088499dd609b81a91906Brian Paul{
1028afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   ASSERT(target == 0 ||
1038afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul          target == GL_TEXTURE_1D ||
1048afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul          target == GL_TEXTURE_2D ||
1058afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul          target == GL_TEXTURE_3D ||
1068afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul          target == GL_TEXTURE_CUBE_MAP_ARB ||
107bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick          target == GL_TEXTURE_RECTANGLE_NV ||
108bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick          target == GL_TEXTURE_1D_ARRAY_EXT ||
109874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul          target == GL_TEXTURE_2D_ARRAY_EXT ||
1100c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu          target == GL_TEXTURE_EXTERNAL_OES ||
111874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul          target == GL_TEXTURE_BUFFER);
112420ef64f18208a54b97e96936b741dc1531e45c8Brian Paul
1136bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul   memset(obj, 0, sizeof(*obj));
114a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* init the non-zero fields */
1159e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   _glthread_INIT_MUTEX(obj->Mutex);
116a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->RefCount = 1;
117a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->Name = name;
118a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->Target = target;
119a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   obj->Priority = 1.0F;
120ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->BaseLevel = 0;
121ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->MaxLevel = 1000;
122ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul
1230c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   /* must be one; no support for (YUV) planes in separate buffers */
1240c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   obj->RequiredTextureImageUnits = 1;
1250c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu
126ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   /* sampler state */
1270c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   if (target == GL_TEXTURE_RECTANGLE_NV ||
1280c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu       target == GL_TEXTURE_EXTERNAL_OES) {
129ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
130ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
131ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
132ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.MinFilter = GL_LINEAR;
133afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
134a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   else {
135ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapS = GL_REPEAT;
136ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapT = GL_REPEAT;
137ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapR = GL_REPEAT;
138ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.MinFilter = GL_NEAREST_MIPMAP_LINEAR;
139a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   }
140ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.MagFilter = GL_LINEAR;
141ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.MinLod = -1000.0;
142ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.MaxLod = 1000.0;
143ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.LodBias = 0.0;
144ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.MaxAnisotropy = 1.0;
145ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.CompareMode = GL_NONE;         /* ARB_shadow */
146ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.CompareFunc = GL_LEQUAL;       /* ARB_shadow */
147ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.CompareFailValue = 0.0F;       /* ARB_shadow_ambient */
148ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.DepthMode = GL_LUMINANCE;      /* ARB_depth_texture */
149a19c42ffc606b594558a0c4f981662442ad6bb83Marek Olšák   obj->Sampler.CubeMapSeamless = GL_FALSE;
1504a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   obj->Swizzle[0] = GL_RED;
1514a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   obj->Swizzle[1] = GL_GREEN;
1524a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   obj->Swizzle[2] = GL_BLUE;
1534a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   obj->Swizzle[3] = GL_ALPHA;
1544a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   obj->_Swizzle = SWIZZLE_NOOP;
155ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.sRGBDecode = GL_DECODE_EXT;
156afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
157afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
158afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1596dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
1606a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul * Some texture initialization can't be finished until we know which
1616a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul * target it's getting bound to (GL_TEXTURE_1D/2D/etc).
1626a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul */
1636a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paulstatic void
164f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergfinish_texture_init(struct gl_context *ctx, GLenum target,
1656a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul                    struct gl_texture_object *obj)
1666a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul{
1676a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul   assert(obj->Target == 0);
1686a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul
1690c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   if (target == GL_TEXTURE_RECTANGLE_NV ||
1700c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu       target == GL_TEXTURE_EXTERNAL_OES) {
1716a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul      /* have to init wrap and filter state here - kind of klunky */
172ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
173ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
174ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
175ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.MinFilter = GL_LINEAR;
1766a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul      if (ctx->Driver.TexParameter) {
1776a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
1786a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
1796a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
1806a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
1816a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
1826a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_MIN_FILTER, fparam_filter);
1836a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul      }
1846a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul   }
1856a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul}
1866a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul
1876a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul
1886a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul/**
1896dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Deallocate a texture object struct.  It should have already been
1906dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * removed from the texture object pool.
1919e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian * Called via ctx->Driver.DeleteTexture() if not overriden by a driver.
1926dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
1936dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param shared the shared GL state to which the object belongs.
1941eee1bac1f6d911e6124daafc9b9291666d91cefVinson Lee * \param texObj the texture object to delete.
195afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
196a3f137094cd965d27e1b088499dd609b81a91906Brian Paulvoid
19776114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul_mesa_delete_texture_object(struct gl_context *ctx,
19876114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul                            struct gl_texture_object *texObj)
199afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
20018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   GLuint i, face;
201afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
2029e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   /* Set Target to an invalid value.  With some assertions elsewhere
2039e01b915f1243a3f551cb795b7124bd1e52ca15fBrian    * we can try to detect possible use of deleted textures.
2049e01b915f1243a3f551cb795b7124bd1e52ca15fBrian    */
2059e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   texObj->Target = 0x99;
2069e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
207a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* free the texture images */
20818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   for (face = 0; face < 6; face++) {
20918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
21076114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul         if (texObj->Image[face][i]) {
211146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paul            ctx->Driver.DeleteTextureImage(ctx, texObj->Image[face][i]);
21276114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul         }
213afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
214afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
215afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
216874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul   _mesa_reference_buffer_object(ctx, &texObj->BufferObject, NULL);
217874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul
2189e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   /* destroy the mutex -- it may have allocated memory (eg on bsd) */
2199e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   _glthread_DESTROY_MUTEX(texObj->Mutex);
2209e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
221a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* free this object */
22232f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   free(texObj);
223a3f137094cd965d27e1b088499dd609b81a91906Brian Paul}
224a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
225a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
226a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
2276dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
22885d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul * Copy texture object state from one texture object to another.
229bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul * Use for glPush/PopAttrib.
2306dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
2316dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param dest destination texture object.
2326dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param src source texture object.
23385d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul */
23485d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paulvoid
23585d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul_mesa_copy_texture_object( struct gl_texture_object *dest,
23685d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul                           const struct gl_texture_object *src )
23785d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul{
238145d762044f795bf9d68f28079cc5e5d3056920eBrian   dest->Target = src->Target;
23985d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->Name = src->Name;
24085d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->Priority = src->Priority;
241ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.BorderColor.f[0] = src->Sampler.BorderColor.f[0];
242ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.BorderColor.f[1] = src->Sampler.BorderColor.f[1];
243ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.BorderColor.f[2] = src->Sampler.BorderColor.f[2];
244ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.BorderColor.f[3] = src->Sampler.BorderColor.f[3];
245ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.WrapS = src->Sampler.WrapS;
246ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.WrapT = src->Sampler.WrapT;
247ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.WrapR = src->Sampler.WrapR;
248ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.MinFilter = src->Sampler.MinFilter;
249ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.MagFilter = src->Sampler.MagFilter;
250ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.MinLod = src->Sampler.MinLod;
251ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.MaxLod = src->Sampler.MaxLod;
252ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.LodBias = src->Sampler.LodBias;
25385d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->BaseLevel = src->BaseLevel;
25485d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->MaxLevel = src->MaxLevel;
255ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.MaxAnisotropy = src->Sampler.MaxAnisotropy;
256ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.CompareMode = src->Sampler.CompareMode;
257ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.CompareFunc = src->Sampler.CompareFunc;
258ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.CompareFailValue = src->Sampler.CompareFailValue;
259a19c42ffc606b594558a0c4f981662442ad6bb83Marek Olšák   dest->Sampler.CubeMapSeamless = src->Sampler.CubeMapSeamless;
260ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.DepthMode = src->Sampler.DepthMode;
2618a506374536497495bac27db6cd15ffd06bb01a2Marek Olšák   dest->Sampler.sRGBDecode = src->Sampler.sRGBDecode;
26285d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->_MaxLevel = src->_MaxLevel;
26385d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->_MaxLambda = src->_MaxLambda;
26485d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->GenerateMipmap = src->GenerateMipmap;
265227315278dea9095cee6e508d03b28720b2e7880Brian   dest->_Complete = src->_Complete;
2664a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   COPY_4V(dest->Swizzle, src->Swizzle);
2674a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   dest->_Swizzle = src->_Swizzle;
2680c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu
2690c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   dest->RequiredTextureImageUnits = src->RequiredTextureImageUnits;
27085d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul}
27185d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul
27285d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul
2736dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
27476114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul * Free all texture images of the given texture object.
27542b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu *
27642b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \param ctx GL context.
27742b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \param t texture object.
27842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu *
27942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \sa _mesa_clear_texture_image().
28042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu */
28142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wuvoid
28276114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul_mesa_clear_texture_object(struct gl_context *ctx,
28376114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul                           struct gl_texture_object *texObj)
28442b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu{
28542b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   GLuint i, j;
28642b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
28742b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   if (texObj->Target == 0)
28842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu      return;
28942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
29042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   for (i = 0; i < MAX_FACES; i++) {
29142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu      for (j = 0; j < MAX_TEXTURE_LEVELS; j++) {
29242b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu         struct gl_texture_image *texImage = texObj->Image[i][j];
29342b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu         if (texImage)
29442b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu            _mesa_clear_texture_image(ctx, texImage);
29542b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu      }
29642b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   }
29742b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu}
29842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
29942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
30042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu/**
3019e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * Check if the given texture object is valid by examining its Target field.
3029e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * For debugging only.
3039e01b915f1243a3f551cb795b7124bd1e52ca15fBrian */
3049e01b915f1243a3f551cb795b7124bd1e52ca15fBrianstatic GLboolean
3059e01b915f1243a3f551cb795b7124bd1e52ca15fBrianvalid_texture_object(const struct gl_texture_object *tex)
3069e01b915f1243a3f551cb795b7124bd1e52ca15fBrian{
3079e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   switch (tex->Target) {
3089e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case 0:
3099e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_1D:
3109e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_2D:
3119e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_3D:
3129e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_CUBE_MAP_ARB:
3139e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_RECTANGLE_NV:
3149e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_1D_ARRAY_EXT:
3159e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_2D_ARRAY_EXT:
316874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul   case GL_TEXTURE_BUFFER:
3170c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   case GL_TEXTURE_EXTERNAL_OES:
3189e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      return GL_TRUE;
3199e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case 0x99:
3209e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      _mesa_problem(NULL, "invalid reference to a deleted texture object");
3219e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      return GL_FALSE;
3229e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   default:
32343d8ace88da80848035827c7bb4bbf5530b59a7cBrian Paul      _mesa_problem(NULL, "invalid texture object Target 0x%x, Id = %u",
32443d8ace88da80848035827c7bb4bbf5530b59a7cBrian Paul                    tex->Target, tex->Name);
3259e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      return GL_FALSE;
3269e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   }
3279e01b915f1243a3f551cb795b7124bd1e52ca15fBrian}
3289e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3299e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3309e01b915f1243a3f551cb795b7124bd1e52ca15fBrian/**
3319e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * Reference (or unreference) a texture object.
3329e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero).
3339e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * If 'tex' is non-null, increment its refcount.
334db0f2b363750d57652140c68c9436f1d2d540a87Brian Paul * This is normally only called from the _mesa_reference_texobj() macro
335db0f2b363750d57652140c68c9436f1d2d540a87Brian Paul * when there's a real pointer change.
3369e01b915f1243a3f551cb795b7124bd1e52ca15fBrian */
3379e01b915f1243a3f551cb795b7124bd1e52ca15fBrianvoid
338db0f2b363750d57652140c68c9436f1d2d540a87Brian Paul_mesa_reference_texobj_(struct gl_texture_object **ptr,
339db0f2b363750d57652140c68c9436f1d2d540a87Brian Paul                        struct gl_texture_object *tex)
3409e01b915f1243a3f551cb795b7124bd1e52ca15fBrian{
3419e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   assert(ptr);
3429e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3439e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   if (*ptr) {
3449e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      /* Unreference the old texture */
3459e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      GLboolean deleteFlag = GL_FALSE;
3469e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      struct gl_texture_object *oldTex = *ptr;
3479e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
34855228878420733e77a09c67d5175e90e4b2e7245Brian Paul      ASSERT(valid_texture_object(oldTex));
34955228878420733e77a09c67d5175e90e4b2e7245Brian Paul      (void) valid_texture_object; /* silence warning in release builds */
3509e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3519e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      _glthread_LOCK_MUTEX(oldTex->Mutex);
3529e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      ASSERT(oldTex->RefCount > 0);
3539e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      oldTex->RefCount--;
354145d762044f795bf9d68f28079cc5e5d3056920eBrian
3559e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      deleteFlag = (oldTex->RefCount == 0);
3569e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      _glthread_UNLOCK_MUTEX(oldTex->Mutex);
3579e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3589e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      if (deleteFlag) {
3599e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         GET_CURRENT_CONTEXT(ctx);
360dc73217294efcba83c46183ed2f208250217486fBrian         if (ctx)
361dc73217294efcba83c46183ed2f208250217486fBrian            ctx->Driver.DeleteTexture(ctx, oldTex);
362dc73217294efcba83c46183ed2f208250217486fBrian         else
363dc73217294efcba83c46183ed2f208250217486fBrian            _mesa_problem(NULL, "Unable to delete texture, no context");
3649e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      }
3659e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3669e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      *ptr = NULL;
3679e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   }
3689e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   assert(!*ptr);
3699e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3709e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   if (tex) {
3719e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      /* reference new texture */
372c10002361c3bc175ec12d667e762e51a2cc79b47Brian Paul      ASSERT(valid_texture_object(tex));
3739e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      _glthread_LOCK_MUTEX(tex->Mutex);
3749e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      if (tex->RefCount == 0) {
3759e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         /* this texture's being deleted (look just above) */
3769e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         /* Not sure this can every really happen.  Warn if it does. */
3779e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         _mesa_problem(NULL, "referencing deleted texture object");
3789e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         *ptr = NULL;
3799e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      }
3809e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      else {
3819e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         tex->RefCount++;
3829e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         *ptr = tex;
3839e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      }
3849e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      _glthread_UNLOCK_MUTEX(tex->Mutex);
3859e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   }
3869e01b915f1243a3f551cb795b7124bd1e52ca15fBrian}
3879e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3889e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3899e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3909e01b915f1243a3f551cb795b7124bd1e52ca15fBrian/**
3916dca66b6209378092fcaaeaeaf738629a146fad8Brian Paul * Mark a texture object as incomplete.
3926dca66b6209378092fcaaeaeaf738629a146fad8Brian Paul * \param t  texture object
3936dca66b6209378092fcaaeaeaf738629a146fad8Brian Paul * \param fmt...  string describing why it's incomplete (for debugging).
394a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul */
39521d073d55ad668494fa19977fe06369194eb1ec5Brian Paulstatic void
3966dca66b6209378092fcaaeaeaf738629a146fad8Brian Paulincomplete(struct gl_texture_object *t, const char *fmt, ...)
39721d073d55ad668494fa19977fe06369194eb1ec5Brian Paul{
39861f25216e3b55ee0b3c4f479da9bad3e5f0cae77Brian Paul#if 0
3991210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt   va_list args;
4001210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt   char s[100];
4011210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt
4021210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt   va_start(args, fmt);
4031210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt   vsnprintf(s, sizeof(s), fmt, args);
4041210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt   va_end(args);
4051210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt
4061210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt   printf("Texture Obj %d incomplete because: %s\n", t->Name, s);
40721d073d55ad668494fa19977fe06369194eb1ec5Brian Paul#endif
4086dca66b6209378092fcaaeaeaf738629a146fad8Brian Paul   t->_Complete = GL_FALSE;
40961f25216e3b55ee0b3c4f479da9bad3e5f0cae77Brian Paul}
410afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
411afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
4126dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
413a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul * Examine a texture object to determine if it is complete.
4146dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
4156dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE
4166dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * accordingly.
4176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
4186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param ctx GL context.
4196dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param t texture object.
4206dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
4216dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * According to the texture target, verifies that each of the mipmaps is
4226dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * present and has the expected size.
423afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
42435d5301a54153930ee6fd60dff1010ce9f901397Brian Paulvoid
425f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_test_texobj_completeness( const struct gl_context *ctx,
42635d5301a54153930ee6fd60dff1010ce9f901397Brian Paul                                struct gl_texture_object *t )
427afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
42863ec4238236479a57420c6b43a09d79eff624928Brian Paul   const GLint baseLevel = t->BaseLevel;
429cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   GLint maxLog2 = 0, maxLevels = 0;
43063ec4238236479a57420c6b43a09d79eff624928Brian Paul
431227315278dea9095cee6e508d03b28720b2e7880Brian   t->_Complete = GL_TRUE;  /* be optimistic */
432afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
4331126aa86bf9ca223218695eec1f41c6523068961Ian Romanick   /* Detect cases where the application set the base level to an invalid
4341126aa86bf9ca223218695eec1f41c6523068961Ian Romanick    * value.
4351126aa86bf9ca223218695eec1f41c6523068961Ian Romanick    */
4363de8fff45d04fd7e702cd656ba97cafd348c3981Brian Paul   if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) {
4371210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt      incomplete(t, "base level = %d is invalid", baseLevel);
4381126aa86bf9ca223218695eec1f41c6523068961Ian Romanick      return;
4391126aa86bf9ca223218695eec1f41c6523068961Ian Romanick   }
4401126aa86bf9ca223218695eec1f41c6523068961Ian Romanick
4414c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul   if (t->MaxLevel < baseLevel) {
4424c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul      incomplete(t, "MAX_LEVEL (%d) < BASE_LEVEL (%d)",
4434c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul		 t->MaxLevel, baseLevel);
4444c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul      return;
4454c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul   }
4464c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul
447a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul   /* Always need the base level image */
44818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   if (!t->Image[0][baseLevel]) {
4491210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt      incomplete(t, "Image[baseLevel=%d] == NULL", baseLevel);
450afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
451afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
452afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
453973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul   /* Check width/height/depth for zero */
45418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   if (t->Image[0][baseLevel]->Width == 0 ||
45518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell       t->Image[0][baseLevel]->Height == 0 ||
45618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell       t->Image[0][baseLevel]->Depth == 0) {
457973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul      incomplete(t, "texture width = 0");
458973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul      return;
459973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul   }
460973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul
4614c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the
4624c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul    * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state).
4634c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul    */
4644c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   switch (t->Target) {
4654c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_1D:
4664c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_1D_ARRAY_EXT:
46718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      maxLog2 = t->Image[0][baseLevel]->WidthLog2;
468cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      maxLevels = ctx->Const.MaxTextureLevels;
4694c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul      break;
4704c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_2D:
4714c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_2D_ARRAY_EXT:
47218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,
47318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                     t->Image[0][baseLevel]->HeightLog2);
4748afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLevels = ctx->Const.MaxTextureLevels;
4754c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul      break;
4764c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_3D:
477cfd5b14dac6a197be3fa85b5448b45802951aa3dBrian Paul      maxLog2 = MAX3(t->Image[0][baseLevel]->WidthLog2,
478cfd5b14dac6a197be3fa85b5448b45802951aa3dBrian Paul                     t->Image[0][baseLevel]->HeightLog2,
479cfd5b14dac6a197be3fa85b5448b45802951aa3dBrian Paul                     t->Image[0][baseLevel]->DepthLog2);
480cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      maxLevels = ctx->Const.Max3DTextureLevels;
4814c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul      break;
4824c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_CUBE_MAP_ARB:
48318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      maxLog2 = MAX2(t->Image[0][baseLevel]->WidthLog2,
48418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell                     t->Image[0][baseLevel]->HeightLog2);
4858afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLevels = ctx->Const.MaxCubeTextureLevels;
4864c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul      break;
4874c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_RECTANGLE_NV:
4884c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_BUFFER:
4894c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_EXTERNAL_OES:
4908afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLog2 = 0;  /* not applicable */
4918afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLevels = 1;  /* no mipmapping */
4924c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul      break;
4934c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   default:
4948afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness");
495cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      return;
496cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   }
497cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul
498cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   ASSERT(maxLevels > 0);
499afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
500083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul   t->_MaxLevel = baseLevel + maxLog2;
501083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul   t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel);
502cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1);
503afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
504083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul   /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */
5054c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul   t->_MaxLambda = (GLfloat) (t->_MaxLevel - baseLevel);
506afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
50768c3d21b6857ec39f0849867355b736191823479Brian Paul   if (t->Immutable) {
50868c3d21b6857ec39f0849867355b736191823479Brian Paul      /* This texture object was created with glTexStorage1/2/3D() so we
50968c3d21b6857ec39f0849867355b736191823479Brian Paul       * know that all the mipmap levels are the right size and all cube
51068c3d21b6857ec39f0849867355b736191823479Brian Paul       * map faces are the same size.
51168c3d21b6857ec39f0849867355b736191823479Brian Paul       * We don't need to do any of the additional checks below.
51268c3d21b6857ec39f0849867355b736191823479Brian Paul       */
51368c3d21b6857ec39f0849867355b736191823479Brian Paul      return;
51468c3d21b6857ec39f0849867355b736191823479Brian Paul   }
51568c3d21b6857ec39f0849867355b736191823479Brian Paul
5168afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
517a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      /* make sure that all six cube map level 0 images are the same size */
51818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      const GLuint w = t->Image[0][baseLevel]->Width2;
51918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      const GLuint h = t->Image[0][baseLevel]->Height2;
52018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      GLuint face;
52118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      for (face = 1; face < 6; face++) {
52276114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul         if (t->Image[face][baseLevel] == NULL ||
52376114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul             t->Image[face][baseLevel]->Width2 != w ||
52476114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul             t->Image[face][baseLevel]->Height2 != h) {
52576114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul            incomplete(t, "Cube face missing or mismatched size");
52676114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul            return;
52776114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul         }
528ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul      }
529ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul   }
530ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul
531887e2cf01a99f7fe1b7c94320b7bdbbf0d6ad2f8Brian Paul   /* extra checking for mipmaps */
532ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   if (t->Sampler.MinFilter != GL_NEAREST && t->Sampler.MinFilter != GL_LINEAR) {
533afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /*
534afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg       * Mipmapping: determine if we have a complete set of mipmaps
535afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg       */
536afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLint i;
53763ec4238236479a57420c6b43a09d79eff624928Brian Paul      GLint minLevel = baseLevel;
538083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul      GLint maxLevel = t->_MaxLevel;
539afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
540afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (minLevel > maxLevel) {
54121d073d55ad668494fa19977fe06369194eb1ec5Brian Paul         incomplete(t, "minLevel > maxLevel");
542afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         return;
543afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
544afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
545afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* Test dimension-independent attributes */
546afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      for (i = minLevel; i <= maxLevel; i++) {
54718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         if (t->Image[0][i]) {
54818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell            if (t->Image[0][i]->TexFormat != t->Image[0][baseLevel]->TexFormat) {
54921d073d55ad668494fa19977fe06369194eb1ec5Brian Paul               incomplete(t, "Format[i] != Format[baseLevel]");
550afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;
551afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
55218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell            if (t->Image[0][i]->Border != t->Image[0][baseLevel]->Border) {
55321d073d55ad668494fa19977fe06369194eb1ec5Brian Paul               incomplete(t, "Border[i] != Border[baseLevel]");
554afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;
555afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
556afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
557afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
558afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
559afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      /* Test things which depend on number of texture image dimensions */
560bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      if ((t->Target == GL_TEXTURE_1D) ||
561bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick          (t->Target == GL_TEXTURE_1D_ARRAY_EXT)) {
562afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* Test 1-D mipmaps */
56318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint width = t->Image[0][baseLevel]->Width2;
564cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul         for (i = baseLevel + 1; i < maxLevels; i++) {
565ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width > 1) {
566afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               width /= 2;
567afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
568afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (i >= minLevel && i <= maxLevel) {
569ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               const struct gl_texture_image *img = t->Image[0][i];
570ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (!img) {
571ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul                  incomplete(t, "1D Image[%d] is missing", i);
572afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
573afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
574ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (img->Width2 != width ) {
575ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul                  incomplete(t, "1D Image[%d] bad width %u", i, img->Width2);
576afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
577afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
578afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
579ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width == 1) {
580afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;  /* found smallest needed mipmap, all done! */
581afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
582afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
583afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
584bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick      else if ((t->Target == GL_TEXTURE_2D) ||
585bb372f1c9bc08e8b0dca983cb4ba36b2f2f039fbIan Romanick               (t->Target == GL_TEXTURE_2D_ARRAY_EXT)) {
586afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* Test 2-D mipmaps */
58718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint width = t->Image[0][baseLevel]->Width2;
58818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint height = t->Image[0][baseLevel]->Height2;
589cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul         for (i = baseLevel + 1; i < maxLevels; i++) {
590ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width > 1) {
591afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               width /= 2;
592afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
593ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (height > 1) {
594afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               height /= 2;
595afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
596afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (i >= minLevel && i <= maxLevel) {
597ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               const struct gl_texture_image *img = t->Image[0][i];
598ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (!img) {
599ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul                  incomplete(t, "2D Image[%d of %d] is missing", i, maxLevel);
600afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
601afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
602ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (img->Width2 != width) {
603ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul                  incomplete(t, "2D Image[%d] bad width %u", i, img->Width2);
604afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
605afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
606ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (img->Height2 != height) {
607ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul                  incomplete(t, "2D Image[i] bad height %u", i, img->Height2);
608afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
609afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
610afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               if (width==1 && height==1) {
611afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;  /* found smallest needed mipmap, all done! */
612afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
613afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
614afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
615afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
6168afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      else if (t->Target == GL_TEXTURE_3D) {
617afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         /* Test 3-D mipmaps */
61818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint width = t->Image[0][baseLevel]->Width2;
61918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint height = t->Image[0][baseLevel]->Height2;
62018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint depth = t->Image[0][baseLevel]->Depth2;
62176114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul         for (i = baseLevel + 1; i < maxLevels; i++) {
622ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width > 1) {
623afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               width /= 2;
624afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
625ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (height > 1) {
626afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               height /= 2;
627afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
628ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (depth > 1) {
629afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               depth /= 2;
630afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
631afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (i >= minLevel && i <= maxLevel) {
632ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               const struct gl_texture_image *img = t->Image[0][i];
633ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (!img) {
634ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul                  incomplete(t, "3D Image[%d] is missing", i);
635afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
636afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
637ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (img->_BaseFormat == GL_DEPTH_COMPONENT) {
6384182cf60d96a077a66675e89694529b5f9e4b329Brian Paul                  incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
6394182cf60d96a077a66675e89694529b5f9e4b329Brian Paul                  return;
6404182cf60d96a077a66675e89694529b5f9e4b329Brian Paul               }
641ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (img->Width2 != width) {
642ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul                  incomplete(t, "3D Image[%d] bad width %u", i, img->Width2);
643afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
644afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
645ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (img->Height2 != height) {
646ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul                  incomplete(t, "3D Image[%d] bad height %u", i, img->Height2);
647afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
648afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
649ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (img->Depth2 != depth) {
650ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul                  incomplete(t, "3D Image[%d] bad depth %u", i, img->Depth2);
651afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
652afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
653afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
654ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width == 1 && height == 1 && depth == 1) {
655afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               return;  /* found smallest needed mipmap, all done! */
656afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            }
657afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
658afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
6598afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
660ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul         /* make sure 6 cube faces are consistant */
66118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint width = t->Image[0][baseLevel]->Width2;
66218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell         GLuint height = t->Image[0][baseLevel]->Height2;
66376114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul         for (i = baseLevel + 1; i < maxLevels; i++) {
664ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (width > 1) {
665ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul               width /= 2;
666ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            }
667ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (height > 1) {
668ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul               height /= 2;
669ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            }
670ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            if (i >= minLevel && i <= maxLevel) {
67118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	       GLuint face;
67218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	       for (face = 0; face < 6; face++) {
67318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  /* check that we have images defined */
67418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  if (!t->Image[face][i]) {
67518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     incomplete(t, "CubeMap Image[n][i] == NULL");
67618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     return;
67718fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  }
67818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  /* Don't support GL_DEPTH_COMPONENT for cube maps */
679863554168ef34ecb7b72650ced78cc9aed923691Dave Airlie                  if (ctx->VersionMajor < 3 && !ctx->Extensions.EXT_gpu_shader4) {
680863554168ef34ecb7b72650ced78cc9aed923691Dave Airlie                     if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
681863554168ef34ecb7b72650ced78cc9aed923691Dave Airlie                        incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
682863554168ef34ecb7b72650ced78cc9aed923691Dave Airlie                        return;
683863554168ef34ecb7b72650ced78cc9aed923691Dave Airlie                     }
68418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  }
68518fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  /* check that all six images have same size */
68676114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul                  if (t->Image[face][i]->Width2 != width ||
68776114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul                      t->Image[face][i]->Height2 != height) {
68818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     incomplete(t, "CubeMap Image[n][i] bad size");
68918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     return;
69018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  }
69118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	       }
69218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	    }
69318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	    if (width == 1 && height == 1) {
69418fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell	       return;  /* found smallest needed mipmap, all done! */
695ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            }
696ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul         }
697413d6a21f849a689b5c83ea04395856b44fc65a8Brian Paul      }
6988afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
6998afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         /* XXX special checking? */
7008afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      }
701afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      else {
7028afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         /* Target = ??? */
70308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_problem(ctx, "Bug in gl_test_texture_object_completeness\n");
704afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
705afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
706afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
707afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
7083f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
7093f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul/**
710ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul * Check if the given cube map texture is "cube complete" as defined in
711ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul * the OpenGL specification.
712ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul */
713ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian PaulGLboolean
714ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul_mesa_cube_complete(const struct gl_texture_object *texObj)
715ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul{
716ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   const GLint baseLevel = texObj->BaseLevel;
717ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   const struct gl_texture_image *img0, *img;
718ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   GLuint face;
719ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
720ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   if (texObj->Target != GL_TEXTURE_CUBE_MAP)
721ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul      return GL_FALSE;
722ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
723ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS))
724ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul      return GL_FALSE;
725ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
726ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   /* check first face */
727ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   img0 = texObj->Image[0][baseLevel];
728ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   if (!img0 ||
729ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul       img0->Width < 1 ||
730ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul       img0->Width != img0->Height)
731ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul      return GL_FALSE;
732ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
733ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   /* check remaining faces vs. first face */
734ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   for (face = 1; face < 6; face++) {
735ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul      img = texObj->Image[face][baseLevel];
736ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul      if (!img ||
737ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul          img->Width != img0->Width ||
738ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul          img->Height != img0->Height ||
739ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul          img->TexFormat != img0->TexFormat)
740ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul         return GL_FALSE;
741ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   }
742ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
743ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   return GL_TRUE;
744ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul}
745ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
746ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
747ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul/**
74842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * Mark a texture object dirty.  It forces the object to be incomplete
74942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * and optionally forces the context to re-validate its state.
75042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu *
75142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \param ctx GL context.
75242b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \param texObj texture object.
75342b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \param invalidate_state also invalidate context state.
75442b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu */
75542b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wuvoid
756f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj,
75742b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu                   GLboolean invalidate_state)
75842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu{
75942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   texObj->_Complete = GL_FALSE;
76042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   if (invalidate_state)
76142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu      ctx->NewState |= _NEW_TEXTURE;
76242b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu}
76342b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
76442b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
76542b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu/**
766c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul * Return pointer to a default/fallback texture of the given type/target.
767c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul * The texture is an RGBA texture with all texels = (0,0,0,1).
768c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul * That's the value a GLSL sampler should get when sampling from an
7693f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul * incomplete texture.
7703f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul */
7713f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paulstruct gl_texture_object *
772c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
7733f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul{
774c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul   if (!ctx->Shared->FallbackTex[tex]) {
7753f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      /* create fallback texture now */
776c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      const GLsizei width = 1, height = 1, depth = 1;
777c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      GLubyte texel[4];
7783f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      struct gl_texture_object *texObj;
7793f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      struct gl_texture_image *texImage;
78083e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul      gl_format texFormat;
781c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      GLuint dims, face, numFaces = 1;
782c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      GLenum target;
783c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
784c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      texel[0] =
785c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      texel[1] =
786c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      texel[2] = 0x0;
787c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      texel[3] = 0xff;
788c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
789c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      switch (tex) {
790c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_2D_ARRAY_INDEX:
791c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 3;
792c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_2D_ARRAY;
793c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
794c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_1D_ARRAY_INDEX:
795c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 2;
796c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_1D_ARRAY;
797c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
798c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_CUBE_INDEX:
799c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 2;
800c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_CUBE_MAP;
801c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         numFaces = 6;
802c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
803c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_3D_INDEX:
804c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 3;
805c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_3D;
806c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
807c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_RECT_INDEX:
808c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 2;
809c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_RECTANGLE;
810c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
811c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_2D_INDEX:
812c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 2;
813c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_2D;
814c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
815c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_1D_INDEX:
816c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 1;
817c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_1D;
818c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
819c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_BUFFER_INDEX:
820c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_EXTERNAL_INDEX:
821c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      default:
822c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         /* no-op */
823c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         return NULL;
8243f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      }
8253f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
8263f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      /* create texture object */
827c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      texObj = ctx->Driver.NewTextureObject(ctx, 0, target);
828c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      if (!texObj)
829c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         return NULL;
830c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
8313f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      assert(texObj->RefCount == 1);
832ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      texObj->Sampler.MinFilter = GL_NEAREST;
833ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      texObj->Sampler.MagFilter = GL_NEAREST;
8343f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
83583e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul      texFormat = ctx->Driver.ChooseTextureFormat(ctx, GL_RGBA, GL_RGBA,
83683e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul                                                  GL_UNSIGNED_BYTE);
83783e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
838c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      /* need a loop here just for cube maps */
839c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      for (face = 0; face < numFaces; face++) {
840c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         GLenum faceTarget;
8417ac233ec15743763996e59c8b283f7c2e78a7210Brian Paul
842c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         if (target == GL_TEXTURE_CUBE_MAP)
843c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
844c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         else
845c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            faceTarget = target;
846c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
847c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         /* initialize level[0] texture image */
848c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, 0);
849c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
850c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         _mesa_init_teximage_fields(ctx, texImage,
851c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                    width,
852c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                    (dims > 1) ? height : 1,
853c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                    (dims > 2) ? depth : 1,
854c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                    0, /* border */
855c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                    GL_RGBA, texFormat);
856c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
857c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         switch (dims) {
858c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         case 1:
859c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            ctx->Driver.TexImage1D(ctx, texImage, GL_RGBA,
860c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                   width, 0,
861c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                   GL_RGBA, GL_UNSIGNED_BYTE, texel,
862c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                   &ctx->DefaultPacking);
863c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            break;
864c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         case 2:
865c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            ctx->Driver.TexImage2D(ctx, texImage, GL_RGBA,
866c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                   width, height, 0,
867c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                   GL_RGBA, GL_UNSIGNED_BYTE, texel,
868c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                   &ctx->DefaultPacking);
869c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            break;
870c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         case 3:
871c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            ctx->Driver.TexImage3D(ctx, texImage, GL_RGBA,
872c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                   width, height, depth, 0,
873c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                   GL_RGBA, GL_UNSIGNED_BYTE, texel,
874c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                   &ctx->DefaultPacking);
875c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            break;
876c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         default:
877c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            _mesa_problem(ctx, "bad dims in _mesa_get_fallback_texture()");
878c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         }
879c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      }
8803f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
8813f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      _mesa_test_texobj_completeness(ctx, texObj);
8823f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      assert(texObj->_Complete);
8833f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
884c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      ctx->Shared->FallbackTex[tex] = texObj;
8853f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul   }
886c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul   return ctx->Shared->FallbackTex[tex];
8873f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul}
8883f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
8893f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
8906dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@}*/
891afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
892832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
8936dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/***********************************************************************/
8946dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** \name API functions */
8956dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@{*/
896afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
8976dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
8986dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
8996dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Generate texture names.
9006dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9016dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of texture names to be generated.
902a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * \param textures an array in which will hold the generated texture names.
9036dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9046dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glGenTextures().
9056dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9069e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture
9079e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian * IDs which are stored in \p textures.  Corresponding empty texture
9089e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian * objects are also generated.
9096dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell */
910c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
911a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul_mesa_GenTextures( GLsizei n, GLuint *textures )
912afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
913fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
914afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLuint first;
915afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
916cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END(ctx);
917afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
918507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul   if (n < 0) {
91908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
920afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
921afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
922afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
923a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul   if (!textures)
924507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return;
925832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
926832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul   /*
927832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul    * This must be atomic (generation and allocation of texture IDs)
928832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul    */
9299e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
930832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
931bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);
932afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
933afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Allocate new, empty texture objects */
934a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   for (i = 0; i < n; i++) {
935a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      struct gl_texture_object *texObj;
936afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLuint name = first + i;
9378afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      GLenum target = 0;
938d6a0692f9dc055c5e5f0e7c806537ad24aa13709Brian Paul      texObj = ctx->Driver.NewTextureObject(ctx, name, target);
939a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      if (!texObj) {
9409e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian         _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
941a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
942a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
943a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      }
944bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul
945bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul      /* insert into hash table */
946bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul      _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
947bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul
948a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul      textures[i] = name;
949afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
950832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
9519e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
952afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
953afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
954a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul
9556dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
956519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul * Check if the given texture object is bound to the current draw or
957519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul * read framebuffer.  If so, Unbind it.
958519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul */
959519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paulstatic void
96076114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paulunbind_texobj_from_fbo(struct gl_context *ctx,
96176114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul                       struct gl_texture_object *texObj)
962519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul{
963519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul   const GLuint n = (ctx->DrawBuffer == ctx->ReadBuffer) ? 1 : 2;
964519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul   GLuint i;
965519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
966519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul   for (i = 0; i < n; i++) {
967519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul      struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer;
96836ede89687fe2de213f2637ab7acfb80cfd856cdBrian Paul      if (_mesa_is_user_fbo(fb)) {
969519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul         GLuint j;
970519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul         for (j = 0; j < BUFFER_COUNT; j++) {
971519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            if (fb->Attachment[j].Type == GL_TEXTURE &&
972519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul                fb->Attachment[j].Texture == texObj) {
973001e07144332203bb30993eed4181b0e411a18beEric Anholt	       /* Vertices are already flushed by _mesa_DeleteTextures */
974001e07144332203bb30993eed4181b0e411a18beEric Anholt	       ctx->NewState |= _NEW_BUFFERS;
975519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul               _mesa_remove_attachment(ctx, fb->Attachment + j);
976519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            }
977519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul         }
978519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul      }
979519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul   }
980519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul}
981519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
982519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
983519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul/**
984519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul * Check if the given texture object is bound to any texture image units and
9859e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * unbind it if so (revert to default textures).
986519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul */
987519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paulstatic void
98876114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paulunbind_texobj_from_texunits(struct gl_context *ctx,
98976114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul                            struct gl_texture_object *texObj)
990519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul{
9919818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   GLuint u, tex;
992519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
9932e35d90fb9a50562d3c658d45a50e16623028d8eHenri Verbeet   for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
994519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul      struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
9959818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
9969818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul         if (texObj == unit->CurrentTex[tex]) {
9979818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul            _mesa_reference_texobj(&unit->CurrentTex[tex],
998e1bddd159f364fa04ddec22f568fbfeb775d3b47Brian Paul                                   ctx->Shared->DefaultTex[tex]);
9999818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul            ASSERT(unit->CurrentTex[tex]);
10009818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul            break;
10019818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul         }
1002519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul      }
1003519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul   }
1004519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul}
1005519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1006519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1007519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul/**
10086dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Delete named textures.
10096dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
10106dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of textures to be deleted.
1011a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * \param textures array of texture IDs to be deleted.
10126dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
10136dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glDeleteTextures().
10146dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
1015a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * If we're about to delete a texture that's currently bound to any
1016a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * texture unit, unbind the texture first.  Decrement the reference
1017a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * count on the texture object and delete it if it's zero.
1018a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * Recall that texture objects can be shared among several rendering
1019a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * contexts.
1020afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1021c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
1022a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul_mesa_DeleteTextures( GLsizei n, const GLuint *textures)
1023afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
1024fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1025afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
1026cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */
1027afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1028a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul   if (!textures)
1029507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return;
1030507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul
1031a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul   for (i = 0; i < n; i++) {
1032a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul      if (textures[i] > 0) {
1033ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         struct gl_texture_object *delObj
1034ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            = _mesa_lookup_texture(ctx, textures[i]);
10355ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
1036a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         if (delObj) {
103776114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul            _mesa_lock_texture(ctx, delObj);
1038519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1039519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            /* Check if texture is bound to any framebuffer objects.
1040519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul             * If so, unbind.
1041519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul             * See section 4.4.2.3 of GL_EXT_framebuffer_object.
1042519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul             */
1043519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            unbind_texobj_from_fbo(ctx, delObj);
1044519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1045519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            /* Check if this texture is currently bound to any texture units.
10469e01b915f1243a3f551cb795b7124bd1e52ca15fBrian             * If so, unbind it.
104759d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul             */
1048519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            unbind_texobj_from_texunits(ctx, delObj);
1049519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
105076114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul            _mesa_unlock_texture(ctx, delObj);
10519e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
1052a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            ctx->NewState |= _NEW_TEXTURE;
1053afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1054bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul            /* The texture _name_ is now free for re-use.
1055bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul             * Remove it from the hash table now.
1056bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul             */
1057bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul            _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1058bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul            _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
1059bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul            _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1060bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul
1061145d762044f795bf9d68f28079cc5e5d3056920eBrian            /* Unreference the texobj.  If refcount hits zero, the texture
10629e01b915f1243a3f551cb795b7124bd1e52ca15fBrian             * will be deleted.
106342fee73aadd7f37a4f18e57c167e98b7a6294508Brian Paul             */
10649e01b915f1243a3f551cb795b7124bd1e52ca15fBrian            _mesa_reference_texobj(&delObj, NULL);
1065afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
1066afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
1067afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
1068afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
1069afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1070f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul
10716dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
10729818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D
10739818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul * into the corresponding Mesa texture target index.
107409325b9ff456ae475069bac5a04cf10a32235e43Brian Paul * Note that proxy targets are not valid here.
107509325b9ff456ae475069bac5a04cf10a32235e43Brian Paul * \return TEXTURE_x_INDEX or -1 if target is invalid
10769818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul */
10779818734e0148510967ca9ee0d1aa8b196b509f02Brian Paulstatic GLint
10789818734e0148510967ca9ee0d1aa8b196b509f02Brian Paultarget_enum_to_index(GLenum target)
10799818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul{
10809818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   switch (target) {
10819818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_1D:
10829818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return TEXTURE_1D_INDEX;
10839818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_2D:
10849818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return TEXTURE_2D_INDEX;
10859818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_3D:
10869818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return TEXTURE_3D_INDEX;
10879818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_CUBE_MAP_ARB:
10889818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return TEXTURE_CUBE_INDEX;
10899818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_RECTANGLE_NV:
10909818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return TEXTURE_RECT_INDEX;
10919818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_1D_ARRAY_EXT:
10929818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return TEXTURE_1D_ARRAY_INDEX;
10939818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_2D_ARRAY_EXT:
10949818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return TEXTURE_2D_ARRAY_INDEX;
1095874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul   case GL_TEXTURE_BUFFER_ARB:
1096874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul      return TEXTURE_BUFFER_INDEX;
10970c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   case GL_TEXTURE_EXTERNAL_OES:
10980c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu      return TEXTURE_EXTERNAL_INDEX;
10999818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   default:
11009818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return -1;
11019818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   }
11029818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul}
11039818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul
11049818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul
11059818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul/**
11066dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Bind a named texture to a texturing target.
11076dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
11086dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param target texture target.
11096dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texName texture name.
11106dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
11116dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glBindTexture().
11126dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
11136dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Determines the old texture object bound and returns immediately if rebinding
11146dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * the same texture.  Get the current texture which is either a default texture
11156dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * if name is null, a named texture from the hash, or a new texture if the
11166dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * given texture name is new. Increments its reference count, binds it, and
11176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * calls dd_function_table::BindTexture. Decrements the old texture reference
11186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * count and deletes it if it reaches zero.
1119afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1120c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
1121fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_BindTexture( GLenum target, GLuint texName )
1122afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
1123fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1124cbadedb511cfcebaf15029891221211219584fb3Brian Paul   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
1125552f54bf0490dabce3fac6d17e78ac65411fde5cBrian Paul   struct gl_texture_object *newTexObj = NULL;
11269818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   GLint targetIndex;
1127cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END(ctx);
1128afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1129afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
11304753d60dd070bb08d0116076bcc08025c86ce857Brian Paul      _mesa_debug(ctx, "glBindTexture %s %d\n",
1131d09a1d8b29ae5841ae39b5c24c3f4693dd750559Brian Paul                  _mesa_lookup_enum_by_nr(target), (GLint) texName);
1132afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
11339818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   targetIndex = target_enum_to_index(target);
11349818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   if (targetIndex < 0) {
11356a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul      _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)");
11366a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul      return;
11376a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul   }
11389818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   assert(targetIndex < NUM_TEXTURE_TARGETS);
11396a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul
1140f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul   /*
1141a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul    * Get pointer to new texture object (newTexObj)
1142a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul    */
1143fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul   if (texName == 0) {
1144552f54bf0490dabce3fac6d17e78ac65411fde5cBrian Paul      /* Use a default texture object */
1145552f54bf0490dabce3fac6d17e78ac65411fde5cBrian Paul      newTexObj = ctx->Shared->DefaultTex[targetIndex];
1146fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul   }
1147afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   else {
1148a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      /* non-default texture object */
1149ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      newTexObj = _mesa_lookup_texture(ctx, texName);
1150a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      if (newTexObj) {
1151a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         /* error checking */
11528afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         if (newTexObj->Target != 0 && newTexObj->Target != target) {
1153fb71a484133c53d37e9510b96d14ab04724ead79Brian Paul            /* the named texture object's target doesn't match the given target */
11545a2f32b102ab862fb10ba6b89e0b68a71552c674Brian Paul            _mesa_error( ctx, GL_INVALID_OPERATION,
1155ee8dfdf4c9f0bbf4f99a6b78dbddc4871fd80a1cBrian Paul                         "glBindTexture(target mismatch)" );
1156a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            return;
1157a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         }
11586a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         if (newTexObj->Target == 0) {
11596a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul            finish_texture_init(ctx, target, newTexObj);
11608afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         }
1161afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
1162a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      else {
1163a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         /* if this is a new texture id, allocate a texture object now */
1164d6a0692f9dc055c5e5f0e7c806537ad24aa13709Brian Paul         newTexObj = ctx->Driver.NewTextureObject(ctx, texName, target);
1165a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         if (!newTexObj) {
116608836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
1167a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            return;
1168a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         }
1169bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul
1170bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul         /* and insert it into hash table */
1171bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul         _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1172bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul         _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj);
1173bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul         _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1174a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      }
11758afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      newTexObj->Target = target;
1176afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
1177afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
11789e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   assert(valid_texture_object(newTexObj));
11796e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul
1180dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul   /* Check if this texture is only used by this context and is already bound.
1181dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul    * If so, just return.
1182dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul    */
1183dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul   {
1184dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      GLboolean early_out;
1185dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1186dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      early_out = ((ctx->Shared->RefCount == 1)
1187dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul                   && (newTexObj == texUnit->CurrentTex[targetIndex]));
1188dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1189dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      if (early_out) {
1190dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul         return;
1191dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      }
11927f8000db8bd45bb95bda4a4f8535c49b8ef74254Ian Romanick   }
11937f8000db8bd45bb95bda4a4f8535c49b8ef74254Ian Romanick
11949e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   /* flush before changing binding */
1195cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1196cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
11979e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   /* Do the actual binding.  The refcount on the previously bound
11989e01b915f1243a3f551cb795b7124bd1e52ca15fBrian    * texture object will be decremented.  It'll be deleted if the
11999e01b915f1243a3f551cb795b7124bd1e52ca15fBrian    * count hits zero.
12009e01b915f1243a3f551cb795b7124bd1e52ca15fBrian    */
12019818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], newTexObj);
12029818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   ASSERT(texUnit->CurrentTex[targetIndex]);
1203afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1204afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Pass BindTexture call to device driver */
12055e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen   if (ctx->Driver.BindTexture)
1206d6a0692f9dc055c5e5f0e7c806537ad24aa13709Brian Paul      ctx->Driver.BindTexture(ctx, target, newTexObj);
1207afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
1208afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1209f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul
12106dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
12116dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Set texture priorities.
12126dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
12136dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of textures.
12146dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texName texture names.
12156dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param priorities corresponding texture priorities.
12166dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
12176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glPrioritizeTextures().
12186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
12196dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Looks up each texture in the hash, clamps the corresponding priority between
12206dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture.
1221afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1222c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
1223fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,
1224fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul                          const GLclampf *priorities )
1225afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
1226fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1227afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
1228cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1229afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
12306d04725282f32cbd32acbc8b79294a2a056b2158Brian Paul   if (n < 0) {
123108836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" );
1232afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
1233afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
1234afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1235507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul   if (!priorities)
1236507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return;
1237507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul
12386d04725282f32cbd32acbc8b79294a2a056b2158Brian Paul   for (i = 0; i < n; i++) {
12396d04725282f32cbd32acbc8b79294a2a056b2158Brian Paul      if (texName[i] > 0) {
1240ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         struct gl_texture_object *t = _mesa_lookup_texture(ctx, texName[i]);
1241afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         if (t) {
1242afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );
1243afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
1244afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
1245afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
1246a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell
1247a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell   ctx->NewState |= _NEW_TEXTURE;
1248afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
1249afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
125076114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul
125176114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul
12526dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
12536dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * See if textures are loaded in texture memory.
12546dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
12556dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of textures to query.
12566dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texName array with the texture names.
12576dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param residences array which will hold the residence status.
12586dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
12596dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \return GL_TRUE if all textures are resident and \p residences is left unchanged,
12606dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
12612f88139145da99a695680c813ef5cc669eaef034Brian Paul * Note: we assume all textures are always resident
1262afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1263c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall BennettGLboolean GLAPIENTRY
1264bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul_mesa_AreTexturesResident(GLsizei n, const GLuint *texName,
1265bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul                          GLboolean *residences)
1266afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
1267fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1268bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   GLboolean allResident = GL_TRUE;
12692f88139145da99a695680c813ef5cc669eaef034Brian Paul   GLint i;
1270cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
1271afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1272bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   if (n < 0) {
127308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)");
1274afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return GL_FALSE;
1275afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
1276afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1277507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul   if (!texName || !residences)
1278507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return GL_FALSE;
1279507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul
12802f88139145da99a695680c813ef5cc669eaef034Brian Paul   /* We only do error checking on the texture names */
1281bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   for (i = 0; i < n; i++) {
1282afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      struct gl_texture_object *t;
1283bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul      if (texName[i] == 0) {
128424e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
1285afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         return GL_FALSE;
1286afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
1287ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      t = _mesa_lookup_texture(ctx, texName[i]);
128824e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul      if (!t) {
128924e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
129024e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         return GL_FALSE;
129124e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul      }
1292afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
129324e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul
1294bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   return allResident;
1295afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
1296afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
129776114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul
12986dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
12996dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * See if a name corresponds to a texture.
13006dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13016dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texture texture name.
13026dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13036dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE
13046dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * otherwise.
13056dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13066dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glIsTexture().
13076dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13086dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Calls _mesa_HashLookup().
1309afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1310c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall BennettGLboolean GLAPIENTRY
1311fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_IsTexture( GLuint texture )
1312afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
13133ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   struct gl_texture_object *t;
1314fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1315cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
13163ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul
1317b756990b8407d67a15cf7f63683d50dd7f9e3a4eDaniel Borca   if (!texture)
13183ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul      return GL_FALSE;
13193ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul
1320ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   t = _mesa_lookup_texture(ctx, texture);
13213ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul
13223ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   /* IsTexture is true only after object has been bound once. */
13233ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   return t && t->Target;
1324afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
13256dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
1326a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian
1327a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian/**
13283105fd760b8a6fc34438d51d36b65670810626a2Brian Paul * Simplest implementation of texture locking: grab the shared tex
13293105fd760b8a6fc34438d51d36b65670810626a2Brian Paul * mutex.  Examine the shared context state timestamp and if there has
13303105fd760b8a6fc34438d51d36b65670810626a2Brian Paul * been a change, set the appropriate bits in ctx->NewState.
13315ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell *
1332a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian * This is used to deal with synchronizing things when a texture object
1333a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian * is used/modified by different contexts (or threads) which are sharing
1334a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian * the texture.
1335a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian *
1336a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian * See also _mesa_lock/unlock_texture() in teximage.h
13375ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell */
1338a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brianvoid
1339f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_lock_context_textures( struct gl_context *ctx )
13405ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell{
13415ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell   _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
13425ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
13435ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell   if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) {
13445ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell      ctx->NewState |= _NEW_TEXTURE;
13455ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell      ctx->TextureStateTimestamp = ctx->Shared->TextureStateStamp;
13465ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell   }
13475ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell}
13485ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
13495ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
1350a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brianvoid
1351f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_unlock_context_textures( struct gl_context *ctx )
13525ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell{
13535ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell   assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp);
13545ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell   _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
13555ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell}
13565ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
13576dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@}*/
1358