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 */
147c37efbfe4c415b6fd2d4f968220d7c9b62f11ecfPauli Nieminen   obj->DepthMode = GL_LUMINANCE;
148a19c42ffc606b594558a0c4f981662442ad6bb83Marek Olšák   obj->Sampler.CubeMapSeamless = GL_FALSE;
1494a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   obj->Swizzle[0] = GL_RED;
1504a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   obj->Swizzle[1] = GL_GREEN;
1514a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   obj->Swizzle[2] = GL_BLUE;
1524a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   obj->Swizzle[3] = GL_ALPHA;
1534a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   obj->_Swizzle = SWIZZLE_NOOP;
154ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   obj->Sampler.sRGBDecode = GL_DECODE_EXT;
1556d0f5684c1aa1b3563af8ae3db35ff0916a7b922Eric Anholt   obj->BufferObjectFormat = GL_LUMINANCE8;
156664355f05b39303fa0995b72160c82f5bf50e95eEric Anholt   obj->_BufferObjectFormat = MESA_FORMAT_L8;
157afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
158afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
159afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1606dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
1616a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul * Some texture initialization can't be finished until we know which
1626a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul * target it's getting bound to (GL_TEXTURE_1D/2D/etc).
1636a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul */
1646a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paulstatic void
165f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergfinish_texture_init(struct gl_context *ctx, GLenum target,
1666a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul                    struct gl_texture_object *obj)
1676a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul{
1686a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul   assert(obj->Target == 0);
1696a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul
1700c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   if (target == GL_TEXTURE_RECTANGLE_NV ||
1710c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu       target == GL_TEXTURE_EXTERNAL_OES) {
1726a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul      /* have to init wrap and filter state here - kind of klunky */
173ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
174ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
175ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
176ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      obj->Sampler.MinFilter = GL_LINEAR;
1776a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul      if (ctx->Driver.TexParameter) {
1786a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
1796a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
1806a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
1816a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
1826a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
1836a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_MIN_FILTER, fparam_filter);
1846a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul      }
1856a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul   }
1866a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul}
1876a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul
1886a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul
1896a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul/**
1906dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Deallocate a texture object struct.  It should have already been
1916dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * removed from the texture object pool.
1929e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian * Called via ctx->Driver.DeleteTexture() if not overriden by a driver.
1936dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
1946dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param shared the shared GL state to which the object belongs.
1951eee1bac1f6d911e6124daafc9b9291666d91cefVinson Lee * \param texObj the texture object to delete.
196afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
197a3f137094cd965d27e1b088499dd609b81a91906Brian Paulvoid
19876114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul_mesa_delete_texture_object(struct gl_context *ctx,
19976114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul                            struct gl_texture_object *texObj)
200afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
20118fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   GLuint i, face;
202afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
2039e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   /* Set Target to an invalid value.  With some assertions elsewhere
2049e01b915f1243a3f551cb795b7124bd1e52ca15fBrian    * we can try to detect possible use of deleted textures.
2059e01b915f1243a3f551cb795b7124bd1e52ca15fBrian    */
2069e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   texObj->Target = 0x99;
2079e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
208a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* free the texture images */
20918fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   for (face = 0; face < 6; face++) {
21018fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
21176114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul         if (texObj->Image[face][i]) {
212146f536b3332b7a2022bb4ba5e2d1d2ec4bedd98Brian Paul            ctx->Driver.DeleteTextureImage(ctx, texObj->Image[face][i]);
21376114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul         }
214afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
215afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
216afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
217874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul   _mesa_reference_buffer_object(ctx, &texObj->BufferObject, NULL);
218874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul
2199e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   /* destroy the mutex -- it may have allocated memory (eg on bsd) */
2209e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   _glthread_DESTROY_MUTEX(texObj->Mutex);
2219e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
222a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   /* free this object */
22332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg   free(texObj);
224a3f137094cd965d27e1b088499dd609b81a91906Brian Paul}
225a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
226a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
227a3f137094cd965d27e1b088499dd609b81a91906Brian Paul
2286dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
22985d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul * Copy texture object state from one texture object to another.
230bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul * Use for glPush/PopAttrib.
2316dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
2326dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param dest destination texture object.
2336dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param src source texture object.
23485d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul */
23585d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paulvoid
23685d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul_mesa_copy_texture_object( struct gl_texture_object *dest,
23785d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul                           const struct gl_texture_object *src )
23885d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul{
239145d762044f795bf9d68f28079cc5e5d3056920eBrian   dest->Target = src->Target;
24085d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->Name = src->Name;
24185d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->Priority = src->Priority;
242ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.BorderColor.f[0] = src->Sampler.BorderColor.f[0];
243ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.BorderColor.f[1] = src->Sampler.BorderColor.f[1];
244ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.BorderColor.f[2] = src->Sampler.BorderColor.f[2];
245ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.BorderColor.f[3] = src->Sampler.BorderColor.f[3];
246ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.WrapS = src->Sampler.WrapS;
247ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.WrapT = src->Sampler.WrapT;
248ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.WrapR = src->Sampler.WrapR;
249ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.MinFilter = src->Sampler.MinFilter;
250ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.MagFilter = src->Sampler.MagFilter;
251ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.MinLod = src->Sampler.MinLod;
252ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.MaxLod = src->Sampler.MaxLod;
253ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.LodBias = src->Sampler.LodBias;
25485d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->BaseLevel = src->BaseLevel;
25585d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul   dest->MaxLevel = src->MaxLevel;
256ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.MaxAnisotropy = src->Sampler.MaxAnisotropy;
257ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.CompareMode = src->Sampler.CompareMode;
258ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul   dest->Sampler.CompareFunc = src->Sampler.CompareFunc;
259a19c42ffc606b594558a0c4f981662442ad6bb83Marek Olšák   dest->Sampler.CubeMapSeamless = src->Sampler.CubeMapSeamless;
260c37efbfe4c415b6fd2d4f968220d7c9b62f11ecfPauli Nieminen   dest->DepthMode = src->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;
265f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   dest->_BaseComplete = src->_BaseComplete;
266f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   dest->_MipmapComplete = src->_MipmapComplete;
2674a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   COPY_4V(dest->Swizzle, src->Swizzle);
2684a89e51c5f88b57040b361b62e80a57c8248ba4bBrian Paul   dest->_Swizzle = src->_Swizzle;
2690c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu
2700c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   dest->RequiredTextureImageUnits = src->RequiredTextureImageUnits;
27185d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul}
27285d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul
27385d816028a2472e0378afda65e7ab6f7ff4d76b4Brian Paul
2746dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
27576114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul * Free all texture images of the given texture object.
27642b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu *
27742b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \param ctx GL context.
27842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \param t texture object.
27942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu *
28042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \sa _mesa_clear_texture_image().
28142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu */
28242b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wuvoid
28376114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul_mesa_clear_texture_object(struct gl_context *ctx,
28476114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul                           struct gl_texture_object *texObj)
28542b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu{
28642b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   GLuint i, j;
28742b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
28842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   if (texObj->Target == 0)
28942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu      return;
29042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
29142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   for (i = 0; i < MAX_FACES; i++) {
29242b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu      for (j = 0; j < MAX_TEXTURE_LEVELS; j++) {
29342b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu         struct gl_texture_image *texImage = texObj->Image[i][j];
29442b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu         if (texImage)
29542b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu            _mesa_clear_texture_image(ctx, texImage);
29642b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu      }
29742b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   }
29842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu}
29942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
30042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
30142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu/**
3029e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * Check if the given texture object is valid by examining its Target field.
3039e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * For debugging only.
3049e01b915f1243a3f551cb795b7124bd1e52ca15fBrian */
3059e01b915f1243a3f551cb795b7124bd1e52ca15fBrianstatic GLboolean
3069e01b915f1243a3f551cb795b7124bd1e52ca15fBrianvalid_texture_object(const struct gl_texture_object *tex)
3079e01b915f1243a3f551cb795b7124bd1e52ca15fBrian{
3089e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   switch (tex->Target) {
3099e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case 0:
3109e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_1D:
3119e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_2D:
3129e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_3D:
3139e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_CUBE_MAP_ARB:
3149e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_RECTANGLE_NV:
3159e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_1D_ARRAY_EXT:
3169e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case GL_TEXTURE_2D_ARRAY_EXT:
317874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul   case GL_TEXTURE_BUFFER:
3180c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   case GL_TEXTURE_EXTERNAL_OES:
3199e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      return GL_TRUE;
3209e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   case 0x99:
3219e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      _mesa_problem(NULL, "invalid reference to a deleted texture object");
3229e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      return GL_FALSE;
3239e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   default:
32443d8ace88da80848035827c7bb4bbf5530b59a7cBrian Paul      _mesa_problem(NULL, "invalid texture object Target 0x%x, Id = %u",
32543d8ace88da80848035827c7bb4bbf5530b59a7cBrian Paul                    tex->Target, tex->Name);
3269e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      return GL_FALSE;
3279e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   }
3289e01b915f1243a3f551cb795b7124bd1e52ca15fBrian}
3299e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3309e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3319e01b915f1243a3f551cb795b7124bd1e52ca15fBrian/**
3329e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * Reference (or unreference) a texture object.
3339e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero).
3349e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * If 'tex' is non-null, increment its refcount.
335db0f2b363750d57652140c68c9436f1d2d540a87Brian Paul * This is normally only called from the _mesa_reference_texobj() macro
336db0f2b363750d57652140c68c9436f1d2d540a87Brian Paul * when there's a real pointer change.
3379e01b915f1243a3f551cb795b7124bd1e52ca15fBrian */
3389e01b915f1243a3f551cb795b7124bd1e52ca15fBrianvoid
339db0f2b363750d57652140c68c9436f1d2d540a87Brian Paul_mesa_reference_texobj_(struct gl_texture_object **ptr,
340db0f2b363750d57652140c68c9436f1d2d540a87Brian Paul                        struct gl_texture_object *tex)
3419e01b915f1243a3f551cb795b7124bd1e52ca15fBrian{
3429e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   assert(ptr);
3439e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3449e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   if (*ptr) {
3459e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      /* Unreference the old texture */
3469e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      GLboolean deleteFlag = GL_FALSE;
3479e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      struct gl_texture_object *oldTex = *ptr;
3489e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
34955228878420733e77a09c67d5175e90e4b2e7245Brian Paul      ASSERT(valid_texture_object(oldTex));
35055228878420733e77a09c67d5175e90e4b2e7245Brian Paul      (void) valid_texture_object; /* silence warning in release builds */
3519e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3529e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      _glthread_LOCK_MUTEX(oldTex->Mutex);
3539e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      ASSERT(oldTex->RefCount > 0);
3549e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      oldTex->RefCount--;
355145d762044f795bf9d68f28079cc5e5d3056920eBrian
3569e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      deleteFlag = (oldTex->RefCount == 0);
3579e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      _glthread_UNLOCK_MUTEX(oldTex->Mutex);
3589e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3599e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      if (deleteFlag) {
3609e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         GET_CURRENT_CONTEXT(ctx);
361dc73217294efcba83c46183ed2f208250217486fBrian         if (ctx)
362dc73217294efcba83c46183ed2f208250217486fBrian            ctx->Driver.DeleteTexture(ctx, oldTex);
363dc73217294efcba83c46183ed2f208250217486fBrian         else
364dc73217294efcba83c46183ed2f208250217486fBrian            _mesa_problem(NULL, "Unable to delete texture, no context");
3659e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      }
3669e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3679e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      *ptr = NULL;
3689e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   }
3699e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   assert(!*ptr);
3709e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3719e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   if (tex) {
3729e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      /* reference new texture */
373c10002361c3bc175ec12d667e762e51a2cc79b47Brian Paul      ASSERT(valid_texture_object(tex));
3749e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      _glthread_LOCK_MUTEX(tex->Mutex);
3759e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      if (tex->RefCount == 0) {
3769e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         /* this texture's being deleted (look just above) */
3779e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         /* Not sure this can every really happen.  Warn if it does. */
3789e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         _mesa_problem(NULL, "referencing deleted texture object");
3799e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         *ptr = NULL;
3809e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      }
3819e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      else {
3829e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         tex->RefCount++;
3839e01b915f1243a3f551cb795b7124bd1e52ca15fBrian         *ptr = tex;
3849e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      }
3859e01b915f1243a3f551cb795b7124bd1e52ca15fBrian      _glthread_UNLOCK_MUTEX(tex->Mutex);
3869e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   }
3879e01b915f1243a3f551cb795b7124bd1e52ca15fBrian}
3889e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3899e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
390f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paulenum base_mipmap { BASE, MIPMAP };
391f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul
3929e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
3939e01b915f1243a3f551cb795b7124bd1e52ca15fBrian/**
394f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul * Mark a texture object as incomplete.  There are actually three kinds of
395f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul * (in)completeness:
396f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul * 1. "base incomplete": the base level of the texture is invalid so no
397f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul *    texturing is possible.
398f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul * 2. "mipmap incomplete": a non-base level of the texture is invalid so
399f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul *    mipmap filtering isn't possible, but non-mipmap filtering is.
400f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul * 3. "texture incompleteness": some combination of texture state and
401f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul *    sampler state renders the texture incomplete.
402f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul *
4036dca66b6209378092fcaaeaeaf738629a146fad8Brian Paul * \param t  texture object
404f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul * \param bm  either BASE or MIPMAP to indicate what's incomplete
4056dca66b6209378092fcaaeaeaf738629a146fad8Brian Paul * \param fmt...  string describing why it's incomplete (for debugging).
406a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul */
40721d073d55ad668494fa19977fe06369194eb1ec5Brian Paulstatic void
408f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paulincomplete(struct gl_texture_object *t, enum base_mipmap bm,
409f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul           const char *fmt, ...)
41021d073d55ad668494fa19977fe06369194eb1ec5Brian Paul{
41193bcf7825d023d3d7108bc47a7a0929338bba6b9Brian Paul   if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_TEXTURE) {
41293bcf7825d023d3d7108bc47a7a0929338bba6b9Brian Paul      va_list args;
41393bcf7825d023d3d7108bc47a7a0929338bba6b9Brian Paul      char s[100];
4141210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt
41593bcf7825d023d3d7108bc47a7a0929338bba6b9Brian Paul      va_start(args, fmt);
41693bcf7825d023d3d7108bc47a7a0929338bba6b9Brian Paul      vsnprintf(s, sizeof(s), fmt, args);
41793bcf7825d023d3d7108bc47a7a0929338bba6b9Brian Paul      va_end(args);
41893bcf7825d023d3d7108bc47a7a0929338bba6b9Brian Paul
41993bcf7825d023d3d7108bc47a7a0929338bba6b9Brian Paul      _mesa_debug(NULL, "Texture Obj %d incomplete because: %s\n", t->Name, s);
42093bcf7825d023d3d7108bc47a7a0929338bba6b9Brian Paul   }
4211210aa75513391779c87e93f009fcf3e52a79cbfEric Anholt
422f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   if (bm == BASE)
423f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul      t->_BaseComplete = GL_FALSE;
424f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   t->_MipmapComplete = GL_FALSE;
42561f25216e3b55ee0b3c4f479da9bad3e5f0cae77Brian Paul}
426afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
427afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
4286dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
429a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul * Examine a texture object to determine if it is complete.
4306dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
4316dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE
4326dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * accordingly.
4336dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
4346dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param ctx GL context.
4356dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param t texture object.
4366dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
4376dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * According to the texture target, verifies that each of the mipmaps is
4386dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * present and has the expected size.
439afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
44035d5301a54153930ee6fd60dff1010ce9f901397Brian Paulvoid
441f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_test_texobj_completeness( const struct gl_context *ctx,
44235d5301a54153930ee6fd60dff1010ce9f901397Brian Paul                                struct gl_texture_object *t )
443afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
44463ec4238236479a57420c6b43a09d79eff624928Brian Paul   const GLint baseLevel = t->BaseLevel;
445e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul   const struct gl_texture_image *baseImage;
446cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   GLint maxLog2 = 0, maxLevels = 0;
44763ec4238236479a57420c6b43a09d79eff624928Brian Paul
448f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   /* We'll set these to FALSE if tests fail below */
449f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   t->_BaseComplete = GL_TRUE;
450f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   t->_MipmapComplete = GL_TRUE;
451afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
452dcf42dbd066fe633c28afa36820da9e9430038dfEric Anholt   if (t->Target == GL_TEXTURE_BUFFER) {
453dcf42dbd066fe633c28afa36820da9e9430038dfEric Anholt      /* Buffer textures are always considered complete.  The obvious case where
454dcf42dbd066fe633c28afa36820da9e9430038dfEric Anholt       * they would be incomplete (no BO attached) is actually specced to be
455dcf42dbd066fe633c28afa36820da9e9430038dfEric Anholt       * undefined rendering results.
456dcf42dbd066fe633c28afa36820da9e9430038dfEric Anholt       */
457dcf42dbd066fe633c28afa36820da9e9430038dfEric Anholt      return;
458dcf42dbd066fe633c28afa36820da9e9430038dfEric Anholt   }
459dcf42dbd066fe633c28afa36820da9e9430038dfEric Anholt
4601126aa86bf9ca223218695eec1f41c6523068961Ian Romanick   /* Detect cases where the application set the base level to an invalid
4611126aa86bf9ca223218695eec1f41c6523068961Ian Romanick    * value.
4621126aa86bf9ca223218695eec1f41c6523068961Ian Romanick    */
4633de8fff45d04fd7e702cd656ba97cafd348c3981Brian Paul   if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) {
464f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul      incomplete(t, BASE, "base level = %d is invalid", baseLevel);
4651126aa86bf9ca223218695eec1f41c6523068961Ian Romanick      return;
4661126aa86bf9ca223218695eec1f41c6523068961Ian Romanick   }
4671126aa86bf9ca223218695eec1f41c6523068961Ian Romanick
4684c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul   if (t->MaxLevel < baseLevel) {
469f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul      incomplete(t, BASE, "MAX_LEVEL (%d) < BASE_LEVEL (%d)",
4704c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul		 t->MaxLevel, baseLevel);
4714c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul      return;
4724c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul   }
4734c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul
474e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul   baseImage = t->Image[0][baseLevel];
475e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul
476a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul   /* Always need the base level image */
477e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul   if (!baseImage) {
478f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul      incomplete(t, BASE, "Image[baseLevel=%d] == NULL", baseLevel);
479afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
480afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
481afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
482973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul   /* Check width/height/depth for zero */
483e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul   if (baseImage->Width == 0 ||
484e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul       baseImage->Height == 0 ||
485e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul       baseImage->Depth == 0) {
486f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul      incomplete(t, BASE, "texture width or height or depth = 0");
487973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul      return;
488973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul   }
489973da83f6237b5af4a9ee77f32fdfa5c04ecabc8Brian Paul
49073fd269d2f5aa2a0b9bc03ef904b81e263e3cc37Brian Paul   /* Check if the texture values are integer */
49173fd269d2f5aa2a0b9bc03ef904b81e263e3cc37Brian Paul   {
49273fd269d2f5aa2a0b9bc03ef904b81e263e3cc37Brian Paul      GLenum datatype = _mesa_get_format_datatype(baseImage->TexFormat);
49373fd269d2f5aa2a0b9bc03ef904b81e263e3cc37Brian Paul      t->_IsIntegerFormat = datatype == GL_INT || datatype == GL_UNSIGNED_INT;
49473fd269d2f5aa2a0b9bc03ef904b81e263e3cc37Brian Paul   }
49573fd269d2f5aa2a0b9bc03ef904b81e263e3cc37Brian Paul
4964c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the
4974c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul    * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state).
4984c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul    */
4994c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   switch (t->Target) {
5004c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_1D:
5014c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_1D_ARRAY_EXT:
502e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul      maxLog2 = baseImage->WidthLog2;
503cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      maxLevels = ctx->Const.MaxTextureLevels;
5044c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul      break;
5054c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_2D:
5064c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_2D_ARRAY_EXT:
507e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul      maxLog2 = MAX2(baseImage->WidthLog2,
508e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul                     baseImage->HeightLog2);
5098afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLevels = ctx->Const.MaxTextureLevels;
5104c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul      break;
5114c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_3D:
512e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul      maxLog2 = MAX3(baseImage->WidthLog2,
513e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul                     baseImage->HeightLog2,
514e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul                     baseImage->DepthLog2);
515cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      maxLevels = ctx->Const.Max3DTextureLevels;
5164c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul      break;
5174c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_CUBE_MAP_ARB:
518e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul      maxLog2 = MAX2(baseImage->WidthLog2,
519e86d0dea8ec72ad8a93b814d99cdafa021ce8a73Brian Paul                     baseImage->HeightLog2);
5208afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLevels = ctx->Const.MaxCubeTextureLevels;
5214c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul      break;
5224c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_RECTANGLE_NV:
5234c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_BUFFER:
5244c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   case GL_TEXTURE_EXTERNAL_OES:
5258afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLog2 = 0;  /* not applicable */
5268afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      maxLevels = 1;  /* no mipmapping */
5274c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul      break;
5284c385d382f6932d5d88a26dcc9eedf520b3a9ed7Brian Paul   default:
5298afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness");
530cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul      return;
531cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   }
532cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul
533cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul   ASSERT(maxLevels > 0);
534afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
535fbbbb98fc4b5b25321491f3ee46692bd819259a4Brian Paul   t->_MaxLevel = baseLevel + maxLog2;  /* 'p' in the GL spec */
536083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul   t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel);
537fbbbb98fc4b5b25321491f3ee46692bd819259a4Brian Paul   t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1); /* 'q' in the GL spec */
538afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
539083e466f88e1203f08b7699fa34b05d0e45b3172Brian Paul   /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */
5404c9537f7d06af9f7f8a706ecd784ce3b04e132e8Brian Paul   t->_MaxLambda = (GLfloat) (t->_MaxLevel - baseLevel);
541afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
54268c3d21b6857ec39f0849867355b736191823479Brian Paul   if (t->Immutable) {
54368c3d21b6857ec39f0849867355b736191823479Brian Paul      /* This texture object was created with glTexStorage1/2/3D() so we
54468c3d21b6857ec39f0849867355b736191823479Brian Paul       * know that all the mipmap levels are the right size and all cube
54568c3d21b6857ec39f0849867355b736191823479Brian Paul       * map faces are the same size.
54668c3d21b6857ec39f0849867355b736191823479Brian Paul       * We don't need to do any of the additional checks below.
54768c3d21b6857ec39f0849867355b736191823479Brian Paul       */
54868c3d21b6857ec39f0849867355b736191823479Brian Paul      return;
54968c3d21b6857ec39f0849867355b736191823479Brian Paul   }
55068c3d21b6857ec39f0849867355b736191823479Brian Paul
5518afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul   if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
55275f82b5d580296a27ed026bc257763bfe24cfa60Brian Paul      /* Make sure that all six cube map level 0 images are the same size.
55375f82b5d580296a27ed026bc257763bfe24cfa60Brian Paul       * Note:  we know that the image's width==height (we enforce that
55475f82b5d580296a27ed026bc257763bfe24cfa60Brian Paul       * at glTexImage time) so we only need to test the width here.
55575f82b5d580296a27ed026bc257763bfe24cfa60Brian Paul       */
55618fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      GLuint face;
55775f82b5d580296a27ed026bc257763bfe24cfa60Brian Paul      assert(baseImage->Width2 == baseImage->Height);
55818fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell      for (face = 1; face < 6; face++) {
5598b7ba92605c0f21cf6292a1bc2e16e379c0b3be8Eric Anholt         assert(t->Image[face][baseLevel] == NULL ||
5608b7ba92605c0f21cf6292a1bc2e16e379c0b3be8Eric Anholt                t->Image[face][baseLevel]->Width2 ==
56175f82b5d580296a27ed026bc257763bfe24cfa60Brian Paul                t->Image[face][baseLevel]->Height2);
56276114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul         if (t->Image[face][baseLevel] == NULL ||
56375f82b5d580296a27ed026bc257763bfe24cfa60Brian Paul             t->Image[face][baseLevel]->Width2 != baseImage->Width2) {
564f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul            incomplete(t, BASE, "Cube face missing or mismatched size");
56576114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul            return;
56676114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul         }
567ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul      }
568ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul   }
569ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul
570d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul   /*
571f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul    * Do mipmap consistency checking.
572f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul    * Note: we don't care about the current texture sampler state here.
573f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul    * To determine texture completeness we'll either look at _BaseComplete
574f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul    * or _MipmapComplete depending on the current minification filter mode.
575d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul    */
576f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   {
577afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLint i;
578d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul      const GLint minLevel = baseLevel;
579d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul      const GLint maxLevel = t->_MaxLevel;
58046751edca9a95baff81771aa69986fa6e2422ed6Brian Paul      const GLuint numFaces = _mesa_num_tex_faces(t->Target);
581281d0fd3a9cd2b4e97cdb58eb7854f9f90220fc7Brian Paul      GLuint width, height, depth, face;
582afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
583afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      if (minLevel > maxLevel) {
584f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul         incomplete(t, BASE, "minLevel > maxLevel");
585afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         return;
586afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
587afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
588d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul      /* Get the base image's dimensions */
589d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul      width = baseImage->Width2;
590d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul      height = baseImage->Height2;
591d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul      depth = baseImage->Depth2;
592afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
593d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul      /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL textures */
594d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul      for (i = baseLevel + 1; i < maxLevels; i++) {
595d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul         /* Compute the expected size of image at level[i] */
596d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul         if (width > 1) {
597d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul            width /= 2;
598afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
599d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul         if (height > 1 && t->Target != GL_TEXTURE_1D_ARRAY) {
600d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul            height /= 2;
601d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul         }
602d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul         if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY) {
603d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul            depth /= 2;
604d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul         }
605d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul
606d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul         /* loop over cube faces (or single face otherwise) */
607d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul         for (face = 0; face < numFaces; face++) {
608afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            if (i >= minLevel && i <= maxLevel) {
609d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul               const struct gl_texture_image *img = t->Image[face][i];
610d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul
611ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (!img) {
612f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul                  incomplete(t, MIPMAP, "TexImage[%d] is missing", i);
613afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
614afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
615d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul               if (img->TexFormat != baseImage->TexFormat) {
616f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul                  incomplete(t, MIPMAP, "Format[i] != Format[baseLevel]");
617afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
618afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
619d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul               if (img->Border != baseImage->Border) {
620f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul                  incomplete(t, MIPMAP, "Border[i] != Border[baseLevel]");
6214182cf60d96a077a66675e89694529b5f9e4b329Brian Paul                  return;
6224182cf60d96a077a66675e89694529b5f9e4b329Brian Paul               }
623ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (img->Width2 != width) {
624f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul                  incomplete(t, MIPMAP, "TexImage[%d] bad width %u", i, img->Width2);
625afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
626afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
627ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (img->Height2 != height) {
628f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul                  incomplete(t, MIPMAP, "TexImage[%d] bad height %u", i, img->Height2);
629afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
630afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
631ab9136ef750a1209db26d6c9dffe299f4134682eBrian Paul               if (img->Depth2 != depth) {
632f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul                  incomplete(t, MIPMAP, "TexImage[%d] bad depth %u", i, img->Depth2);
633afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg                  return;
634afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg               }
635d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul
636d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul               /* Extra checks for cube textures */
637d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul               if (face > 0) {
638d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul                  /* check that cube faces are the same size */
639d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul                  if (img->Width2 != t->Image[0][i]->Width2 ||
640d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul                      img->Height2 != t->Image[0][i]->Height2) {
641f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul		     incomplete(t, MIPMAP, "CubeMap Image[n][i] bad size");
64218fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		     return;
64318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell		  }
644d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul               }
645ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul            }
646ad817704fa2c6d8449f55565f07ab5592a574fb6Brian Paul         }
647d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul
648d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul         if (width == 1 && height == 1 && depth == 1) {
649d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul            return;  /* found smallest needed mipmap, all done! */
650d335e69b9ab8b3068dc402e22e49483f9caab1dfBrian Paul         }
651afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
652afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
653afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
654afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
6553f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
6563f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul/**
657ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul * Check if the given cube map texture is "cube complete" as defined in
658ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul * the OpenGL specification.
659ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul */
660ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian PaulGLboolean
661ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul_mesa_cube_complete(const struct gl_texture_object *texObj)
662ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul{
663ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   const GLint baseLevel = texObj->BaseLevel;
664ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   const struct gl_texture_image *img0, *img;
665ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   GLuint face;
666ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
667ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   if (texObj->Target != GL_TEXTURE_CUBE_MAP)
668ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul      return GL_FALSE;
669ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
670ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS))
671ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul      return GL_FALSE;
672ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
673ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   /* check first face */
674ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   img0 = texObj->Image[0][baseLevel];
675ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   if (!img0 ||
676ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul       img0->Width < 1 ||
677ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul       img0->Width != img0->Height)
678ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul      return GL_FALSE;
679ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
680ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   /* check remaining faces vs. first face */
681ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   for (face = 1; face < 6; face++) {
682ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul      img = texObj->Image[face][baseLevel];
683ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul      if (!img ||
684ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul          img->Width != img0->Width ||
685ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul          img->Height != img0->Height ||
686ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul          img->TexFormat != img0->TexFormat)
687ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul         return GL_FALSE;
688ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   }
689ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
690ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul   return GL_TRUE;
691ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul}
692ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
693ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul
694ecb7cc3319a74bda1edc226a1103f0e1a86d92a9Brian Paul/**
69542b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * Mark a texture object dirty.  It forces the object to be incomplete
69642b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * and optionally forces the context to re-validate its state.
69742b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu *
69842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \param ctx GL context.
69942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \param texObj texture object.
70042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu * \param invalidate_state also invalidate context state.
70142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu */
70242b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wuvoid
703f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj,
70442b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu                   GLboolean invalidate_state)
70542b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu{
706f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   texObj->_BaseComplete = GL_FALSE;
707f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul   texObj->_MipmapComplete = GL_FALSE;
70842b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu   if (invalidate_state)
70942b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu      ctx->NewState |= _NEW_TEXTURE;
71042b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu}
71142b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
71242b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu
71342b6b067ac68ac1309d0570613bea4a88f745559Chia-I Wu/**
714c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul * Return pointer to a default/fallback texture of the given type/target.
715c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul * The texture is an RGBA texture with all texels = (0,0,0,1).
716c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul * That's the value a GLSL sampler should get when sampling from an
7173f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul * incomplete texture.
7183f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul */
7193f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paulstruct gl_texture_object *
720c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
7213f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul{
722c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul   if (!ctx->Shared->FallbackTex[tex]) {
7233f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      /* create fallback texture now */
724c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      const GLsizei width = 1, height = 1, depth = 1;
725c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      GLubyte texel[4];
7263f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      struct gl_texture_object *texObj;
7273f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      struct gl_texture_image *texImage;
72883e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul      gl_format texFormat;
729c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      GLuint dims, face, numFaces = 1;
730c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      GLenum target;
731c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
732c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      texel[0] =
733c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      texel[1] =
734c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      texel[2] = 0x0;
735c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      texel[3] = 0xff;
736c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
737c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      switch (tex) {
738c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_2D_ARRAY_INDEX:
739c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 3;
740c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_2D_ARRAY;
741c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
742c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_1D_ARRAY_INDEX:
743c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 2;
744c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_1D_ARRAY;
745c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
746c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_CUBE_INDEX:
747c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 2;
748c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_CUBE_MAP;
749c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         numFaces = 6;
750c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
751c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_3D_INDEX:
752c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 3;
753c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_3D;
754c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
755c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_RECT_INDEX:
756c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 2;
757c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_RECTANGLE;
758c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
759c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_2D_INDEX:
760c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 2;
761c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_2D;
762c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
763c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_1D_INDEX:
764c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         dims = 1;
765c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         target = GL_TEXTURE_1D;
766c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         break;
767c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_BUFFER_INDEX:
76818c2ee0df5fa6679996e40c574d37475be230bd7Eric Anholt         dims = 0;
76918c2ee0df5fa6679996e40c574d37475be230bd7Eric Anholt         target = GL_TEXTURE_BUFFER;
77018c2ee0df5fa6679996e40c574d37475be230bd7Eric Anholt         break;
771c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      case TEXTURE_EXTERNAL_INDEX:
772a5848562b501f67e4f51013277b12157d9c7fb18Abdiel Janulgue         dims = 2;
773a5848562b501f67e4f51013277b12157d9c7fb18Abdiel Janulgue         target = GL_TEXTURE_EXTERNAL_OES;
774a5848562b501f67e4f51013277b12157d9c7fb18Abdiel Janulgue         break;
775c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      default:
776c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         /* no-op */
777c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         return NULL;
7783f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      }
7793f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
7803f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      /* create texture object */
781c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      texObj = ctx->Driver.NewTextureObject(ctx, 0, target);
782c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      if (!texObj)
783c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         return NULL;
784c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
7853f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      assert(texObj->RefCount == 1);
786ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      texObj->Sampler.MinFilter = GL_NEAREST;
787ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul      texObj->Sampler.MagFilter = GL_NEAREST;
7883f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
789d47a6ada9ca9670c60fc141fabadf40c63031c08Brian Paul      texFormat = ctx->Driver.ChooseTextureFormat(ctx, target,
790d47a6ada9ca9670c60fc141fabadf40c63031c08Brian Paul                                                  GL_RGBA, GL_RGBA,
79183e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul                                                  GL_UNSIGNED_BYTE);
79283e93b6008213ad86607027e8434ecaccc8b1a2cBrian Paul
793c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      /* need a loop here just for cube maps */
794c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      for (face = 0; face < numFaces; face++) {
795c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         GLenum faceTarget;
7967ac233ec15743763996e59c8b283f7c2e78a7210Brian Paul
797c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         if (target == GL_TEXTURE_CUBE_MAP)
798c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
799c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         else
800c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul            faceTarget = target;
801c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
802c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         /* initialize level[0] texture image */
803c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, 0);
804c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
805c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul         _mesa_init_teximage_fields(ctx, texImage,
806c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                    width,
807c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                    (dims > 1) ? height : 1,
808c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                    (dims > 2) ? depth : 1,
809c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                    0, /* border */
810c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul                                    GL_RGBA, texFormat);
811c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul
812c5af8891805fc4f590c1371c098cdbc704c44e00Pauli Nieminen         ctx->Driver.TexImage(ctx, dims, texImage,
8138f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul                              GL_RGBA, GL_UNSIGNED_BYTE, texel,
8148f5fffe75d2f8ae7c7ee706b53379a25bc673ae4Brian Paul                              &ctx->DefaultPacking);
815c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      }
8163f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
8173f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul      _mesa_test_texobj_completeness(ctx, texObj);
818f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul      assert(texObj->_BaseComplete);
819f4a93e0665881dd58a95abb6525676bd1cc2e6afBrian Paul      assert(texObj->_MipmapComplete);
8203f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
821c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul      ctx->Shared->FallbackTex[tex] = texObj;
8223f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul   }
823c04db7f7fad883891084d7f2e9a0040a17c48fe8Brian Paul   return ctx->Shared->FallbackTex[tex];
8243f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul}
8253f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
8263f25219c7bf0f090502489928f0f018e62c4f6cfBrian Paul
82771d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul/**
82871d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul * Compute the size of the given texture object, in bytes.
82971d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul */
83071d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paulstatic GLuint
83171d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paultexture_size(const struct gl_texture_object *texObj)
83271d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul{
83346751edca9a95baff81771aa69986fa6e2422ed6Brian Paul   const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
83471d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   GLuint face, level, size = 0;
83571d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
83671d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   for (face = 0; face < numFaces; face++) {
83771d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul      for (level = 0; level < MAX_TEXTURE_LEVELS; level++) {
83871d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul         const struct gl_texture_image *img = texObj->Image[face][level];
83971d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul         if (img) {
84071d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul            GLuint sz = _mesa_format_image_size(img->TexFormat, img->Width,
84171d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul                                                img->Height, img->Depth);
84271d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul            size += sz;
84371d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul         }
84471d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul      }
84571d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   }
84671d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
84771d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   return size;
84871d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul}
84971d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
85071d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
85171d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul/**
85271d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul * Callback called from _mesa_HashWalk()
85371d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul */
85471d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paulstatic void
85571d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paulcount_tex_size(GLuint key, void *data, void *userData)
85671d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul{
85771d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   const struct gl_texture_object *texObj =
85871d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul      (const struct gl_texture_object *) data;
85971d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   GLuint *total = (GLuint *) userData;
86071d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
86171d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   *total = *total + texture_size(texObj);
86271d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul}
86371d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
86471d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
86571d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul/**
86671d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul * Compute total size (in bytes) of all textures for the given context.
86771d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul * For debugging purposes.
86871d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul */
86971d69161ab86e88dfbfe9931c03eef9d17de90efBrian PaulGLuint
87071d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul_mesa_total_texture_memory(struct gl_context *ctx)
87171d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul{
87271d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   GLuint tgt, total = 0;
87371d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
87471d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   _mesa_HashWalk(ctx->Shared->TexObjects, count_tex_size, &total);
87571d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
87671d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   /* plus, the default texture objects */
87771d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
87871d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul      total += texture_size(ctx->Shared->DefaultTex[tgt]);
87971d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   }
88071d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
88171d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul   return total;
88271d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul}
88371d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
88407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanickstatic struct gl_texture_object *
88507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanickinvalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture,
88607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick                                 GLint level, const char *name)
88707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick{
88807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   /* The GL_ARB_invalidate_subdata spec says:
88907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *
89007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     "If <texture> is zero or is not the name of a texture, the error
89107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     INVALID_VALUE is generated."
89207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *
89307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    * This performs the error check in a different order than listed in the
89407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    * spec.  We have to get the texture object before we can validate the
89507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    * other parameters against values in the texture object.
89607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    */
89707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   struct gl_texture_object *const t = _mesa_lookup_texture(ctx, texture);
89807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   if (texture == 0 || t == NULL) {
89907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      _mesa_error(ctx, GL_INVALID_VALUE, "%s(texture)", name);
90007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      return NULL;
90107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   }
90271d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
90307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   /* The GL_ARB_invalidate_subdata spec says:
90407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *
90507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     "If <level> is less than zero or greater than the base 2 logarithm
90607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     of the maximum texture width, height, or depth, the error
90707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     INVALID_VALUE is generated."
90807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    */
90907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   if (level < 0 || level > t->MaxLevel) {
91007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name);
91107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      return NULL;
91207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   }
91307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
91407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   /* The GL_ARB_invalidate_subdata spec says:
91507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *
91607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     "If the target of <texture> is TEXTURE_RECTANGLE, TEXTURE_BUFFER,
91707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     TEXTURE_2D_MULTISAMPLE, or TEXTURE_2D_MULTISAMPLE_ARRAY, and <level>
91807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     is not zero, the error INVALID_VALUE is generated."
91907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    */
92007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   if (level != 0) {
92107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      switch (t->Target) {
92207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_RECTANGLE:
92307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_BUFFER:
92407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_2D_MULTISAMPLE:
92507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
92607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name);
92707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         return NULL;
92807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
92907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      default:
93007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         break;
93107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      }
93207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   }
93307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
93407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   return t;
93507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick}
93671d69161ab86e88dfbfe9931c03eef9d17de90efBrian Paul
9376dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@}*/
938afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
939832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
9406dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/***********************************************************************/
9416dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/** \name API functions */
9426dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@{*/
943afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
9446dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
9456dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
9466dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Generate texture names.
9476dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9486dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of texture names to be generated.
949a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * \param textures an array in which will hold the generated texture names.
9506dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9516dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glGenTextures().
9526dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
9539e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture
9549e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian * IDs which are stored in \p textures.  Corresponding empty texture
9559e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian * objects are also generated.
9566dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell */
957c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
958a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul_mesa_GenTextures( GLsizei n, GLuint *textures )
959afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
960fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
961afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLuint first;
962afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
963cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END(ctx);
964afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
965507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul   if (n < 0) {
96608836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
967afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
968afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
969afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
970a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul   if (!textures)
971507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return;
972832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
973832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul   /*
974832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul    * This must be atomic (generation and allocation of texture IDs)
975832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul    */
9769e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
977832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
978bb79790662f56eb71aafd3f020cd86ad810f56b2Brian Paul   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);
979afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
980afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Allocate new, empty texture objects */
981a3f137094cd965d27e1b088499dd609b81a91906Brian Paul   for (i = 0; i < n; i++) {
982a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      struct gl_texture_object *texObj;
983afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      GLuint name = first + i;
9848afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      GLenum target = 0;
985d6a0692f9dc055c5e5f0e7c806537ad24aa13709Brian Paul      texObj = ctx->Driver.NewTextureObject(ctx, name, target);
986a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      if (!texObj) {
9879e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian         _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
988a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
989a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
990a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      }
991bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul
992bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul      /* insert into hash table */
993bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul      _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
994bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul
995a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul      textures[i] = name;
996afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
997832179c50e2cf5de9735241e4767aea4d6fc33bfBrian Paul
9989e3e3883fa42ffee82e8e8ecbf75c153a2215acbBrian   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
999afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
1000afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1001a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul
10026dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
1003519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul * Check if the given texture object is bound to the current draw or
1004519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul * read framebuffer.  If so, Unbind it.
1005519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul */
1006519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paulstatic void
100776114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paulunbind_texobj_from_fbo(struct gl_context *ctx,
100876114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul                       struct gl_texture_object *texObj)
1009519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul{
1010519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul   const GLuint n = (ctx->DrawBuffer == ctx->ReadBuffer) ? 1 : 2;
1011519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul   GLuint i;
1012519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1013519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul   for (i = 0; i < n; i++) {
1014519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul      struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer;
101536ede89687fe2de213f2637ab7acfb80cfd856cdBrian Paul      if (_mesa_is_user_fbo(fb)) {
1016519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul         GLuint j;
1017519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul         for (j = 0; j < BUFFER_COUNT; j++) {
1018519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            if (fb->Attachment[j].Type == GL_TEXTURE &&
1019519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul                fb->Attachment[j].Texture == texObj) {
1020001e07144332203bb30993eed4181b0e411a18beEric Anholt	       /* Vertices are already flushed by _mesa_DeleteTextures */
1021001e07144332203bb30993eed4181b0e411a18beEric Anholt	       ctx->NewState |= _NEW_BUFFERS;
1022519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul               _mesa_remove_attachment(ctx, fb->Attachment + j);
1023519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            }
1024519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul         }
1025519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul      }
1026519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul   }
1027519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul}
1028519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1029519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1030519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul/**
1031519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul * Check if the given texture object is bound to any texture image units and
10329e01b915f1243a3f551cb795b7124bd1e52ca15fBrian * unbind it if so (revert to default textures).
1033519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul */
1034519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paulstatic void
103576114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paulunbind_texobj_from_texunits(struct gl_context *ctx,
103676114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul                            struct gl_texture_object *texObj)
1037519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul{
10389818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   GLuint u, tex;
1039519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
10402e35d90fb9a50562d3c658d45a50e16623028d8eHenri Verbeet   for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
1041519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul      struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
10429818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
10439818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul         if (texObj == unit->CurrentTex[tex]) {
10449818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul            _mesa_reference_texobj(&unit->CurrentTex[tex],
1045e1bddd159f364fa04ddec22f568fbfeb775d3b47Brian Paul                                   ctx->Shared->DefaultTex[tex]);
10469818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul            ASSERT(unit->CurrentTex[tex]);
10479818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul            break;
10489818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul         }
1049519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul      }
1050519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul   }
1051519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul}
1052519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1053519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1054519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul/**
10556dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Delete named textures.
10566dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
10576dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of textures to be deleted.
1058a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * \param textures array of texture IDs to be deleted.
10596dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
10606dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glDeleteTextures().
10616dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
1062a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * If we're about to delete a texture that's currently bound to any
1063a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * texture unit, unbind the texture first.  Decrement the reference
1064a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * count on the texture object and delete it if it's zero.
1065a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * Recall that texture objects can be shared among several rendering
1066a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul * contexts.
1067afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1068c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
1069a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul_mesa_DeleteTextures( GLsizei n, const GLuint *textures)
1070afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
1071fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1072afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
1073cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */
1074afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1075a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul   if (!textures)
1076507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return;
1077507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul
1078a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul   for (i = 0; i < n; i++) {
1079a212e9670ba31b062c48ed9dd23f28f08fa15b5eBrian Paul      if (textures[i] > 0) {
1080ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         struct gl_texture_object *delObj
1081ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            = _mesa_lookup_texture(ctx, textures[i]);
10825ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
1083a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         if (delObj) {
108476114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul            _mesa_lock_texture(ctx, delObj);
1085519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1086519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            /* Check if texture is bound to any framebuffer objects.
1087519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul             * If so, unbind.
1088519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul             * See section 4.4.2.3 of GL_EXT_framebuffer_object.
1089519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul             */
1090519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            unbind_texobj_from_fbo(ctx, delObj);
1091519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
1092519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            /* Check if this texture is currently bound to any texture units.
10939e01b915f1243a3f551cb795b7124bd1e52ca15fBrian             * If so, unbind it.
109459d6da5365c876ba18a66cd51ed52b0e1d96704eBrian Paul             */
1095519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul            unbind_texobj_from_texunits(ctx, delObj);
1096519b23b21f9cd6945fd17cdb26e7a6f531cdeec0Brian Paul
109776114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul            _mesa_unlock_texture(ctx, delObj);
10989e01b915f1243a3f551cb795b7124bd1e52ca15fBrian
1099a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            ctx->NewState |= _NEW_TEXTURE;
1100afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1101bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul            /* The texture _name_ is now free for re-use.
1102bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul             * Remove it from the hash table now.
1103bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul             */
1104bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul            _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1105bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul            _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
1106bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul            _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1107bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul
1108145d762044f795bf9d68f28079cc5e5d3056920eBrian            /* Unreference the texobj.  If refcount hits zero, the texture
11099e01b915f1243a3f551cb795b7124bd1e52ca15fBrian             * will be deleted.
111042fee73aadd7f37a4f18e57c167e98b7a6294508Brian Paul             */
11119e01b915f1243a3f551cb795b7124bd1e52ca15fBrian            _mesa_reference_texobj(&delObj, NULL);
1112afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
1113afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
1114afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
1115afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
1116afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1117f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul
11186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
11199818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D
11209818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul * into the corresponding Mesa texture target index.
112109325b9ff456ae475069bac5a04cf10a32235e43Brian Paul * Note that proxy targets are not valid here.
112209325b9ff456ae475069bac5a04cf10a32235e43Brian Paul * \return TEXTURE_x_INDEX or -1 if target is invalid
11239818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul */
11249818734e0148510967ca9ee0d1aa8b196b509f02Brian Paulstatic GLint
11253f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanicktarget_enum_to_index(struct gl_context *ctx, GLenum target)
11269818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul{
11279818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   switch (target) {
11289818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_1D:
11293f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick      return _mesa_is_desktop_gl(ctx) ? TEXTURE_1D_INDEX : -1;
11309818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_2D:
11319818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return TEXTURE_2D_INDEX;
11329818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_3D:
11339818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return TEXTURE_3D_INDEX;
11349818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_CUBE_MAP_ARB:
11353f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick      return ctx->Extensions.ARB_texture_cube_map
11363f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick         ? TEXTURE_CUBE_INDEX : -1;
11379818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_RECTANGLE_NV:
11383f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle
11393f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick         ? TEXTURE_RECT_INDEX : -1;
11409818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_1D_ARRAY_EXT:
11413f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick      return _mesa_is_desktop_gl(ctx)
11423f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick         && (ctx->Extensions.EXT_texture_array
11433f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick             || ctx->Extensions.MESA_texture_array)
11443f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick         ? TEXTURE_1D_ARRAY_INDEX : -1;
11459818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   case GL_TEXTURE_2D_ARRAY_EXT:
11463f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick      return (_mesa_is_desktop_gl(ctx)
11473f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick              && (ctx->Extensions.EXT_texture_array
11483f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick                  || ctx->Extensions.MESA_texture_array))
11493f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick         || _mesa_is_gles3(ctx)
11503f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick         ? TEXTURE_2D_ARRAY_INDEX : -1;
1151874a2c0b7da62f4dd08dedcec221f55b22e40e95Brian Paul   case GL_TEXTURE_BUFFER_ARB:
11523f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick      return _mesa_is_desktop_gl(ctx)
11533f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick         && ctx->Extensions.ARB_texture_buffer_object
11543f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick         ? TEXTURE_BUFFER_INDEX : -1;
11550c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu   case GL_TEXTURE_EXTERNAL_OES:
11563f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick      return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external
11573f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick         ? TEXTURE_EXTERNAL_INDEX : -1;
11589818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   default:
11599818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul      return -1;
11609818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   }
11619818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul}
11629818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul
11639818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul
11649818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul/**
11656dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Bind a named texture to a texturing target.
11666dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
11676dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param target texture target.
11686dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texName texture name.
11696dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
11706dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glBindTexture().
11716dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
11726dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Determines the old texture object bound and returns immediately if rebinding
11736dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * the same texture.  Get the current texture which is either a default texture
11746dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * if name is null, a named texture from the hash, or a new texture if the
11756dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * given texture name is new. Increments its reference count, binds it, and
11766dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * calls dd_function_table::BindTexture. Decrements the old texture reference
11776dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * count and deletes it if it reaches zero.
1178afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1179c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
1180fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_BindTexture( GLenum target, GLuint texName )
1181afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
1182fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1183cbadedb511cfcebaf15029891221211219584fb3Brian Paul   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
1184552f54bf0490dabce3fac6d17e78ac65411fde5cBrian Paul   struct gl_texture_object *newTexObj = NULL;
11859818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   GLint targetIndex;
1186cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END(ctx);
1187afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1188afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
11894753d60dd070bb08d0116076bcc08025c86ce857Brian Paul      _mesa_debug(ctx, "glBindTexture %s %d\n",
1190d09a1d8b29ae5841ae39b5c24c3f4693dd750559Brian Paul                  _mesa_lookup_enum_by_nr(target), (GLint) texName);
1191afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
11923f7c8364cf1d763f04413aecfac66df5534aeb34Ian Romanick   targetIndex = target_enum_to_index(ctx, target);
11939818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   if (targetIndex < 0) {
11946a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul      _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)");
11956a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul      return;
11966a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul   }
11979818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   assert(targetIndex < NUM_TEXTURE_TARGETS);
11986a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul
1199f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul   /*
1200a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul    * Get pointer to new texture object (newTexObj)
1201a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul    */
1202fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul   if (texName == 0) {
1203552f54bf0490dabce3fac6d17e78ac65411fde5cBrian Paul      /* Use a default texture object */
1204552f54bf0490dabce3fac6d17e78ac65411fde5cBrian Paul      newTexObj = ctx->Shared->DefaultTex[targetIndex];
1205fc4b44399a07a7a7559f20ceab8a791209b4d875Brian Paul   }
1206afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   else {
1207a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      /* non-default texture object */
1208ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      newTexObj = _mesa_lookup_texture(ctx, texName);
1209a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      if (newTexObj) {
1210a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         /* error checking */
12118afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         if (newTexObj->Target != 0 && newTexObj->Target != target) {
1212fb71a484133c53d37e9510b96d14ab04724ead79Brian Paul            /* the named texture object's target doesn't match the given target */
12135a2f32b102ab862fb10ba6b89e0b68a71552c674Brian Paul            _mesa_error( ctx, GL_INVALID_OPERATION,
1214ee8dfdf4c9f0bbf4f99a6b78dbddc4871fd80a1cBrian Paul                         "glBindTexture(target mismatch)" );
1215a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            return;
1216a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         }
12176a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul         if (newTexObj->Target == 0) {
12186a00625fbb7e42a71daa87f982eee8e9077a0679Brian Paul            finish_texture_init(ctx, target, newTexObj);
12198afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul         }
1220afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
1221a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      else {
122291107b4ccf7a47633fce98b9ccfba7f559098cb7Ian Romanick         if (ctx->API == API_OPENGL_CORE) {
122391107b4ccf7a47633fce98b9ccfba7f559098cb7Ian Romanick            _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTexture");
122491107b4ccf7a47633fce98b9ccfba7f559098cb7Ian Romanick            return;
122591107b4ccf7a47633fce98b9ccfba7f559098cb7Ian Romanick         }
122691107b4ccf7a47633fce98b9ccfba7f559098cb7Ian Romanick
1227a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         /* if this is a new texture id, allocate a texture object now */
1228d6a0692f9dc055c5e5f0e7c806537ad24aa13709Brian Paul         newTexObj = ctx->Driver.NewTextureObject(ctx, texName, target);
1229a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         if (!newTexObj) {
123008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
1231a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul            return;
1232a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul         }
1233bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul
1234bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul         /* and insert it into hash table */
1235bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul         _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1236bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul         _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj);
1237bb7d5f8837a9c7658a18dbaf02d52583e29443e3Brian Paul         _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1238a852378a6289d154364dde440f89a39bbfc33e2dBrian Paul      }
12398afe7de8deaf3c9613fd68b344de8c52b02b1879Brian Paul      newTexObj->Target = target;
1240afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
1241afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
12429e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   assert(valid_texture_object(newTexObj));
12436e6d4c66bd7fd64162ee453b143d7388bb051444Brian Paul
1244dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul   /* Check if this texture is only used by this context and is already bound.
1245dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul    * If so, just return.
1246dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul    */
1247dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul   {
1248dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      GLboolean early_out;
1249dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
1250dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      early_out = ((ctx->Shared->RefCount == 1)
1251dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul                   && (newTexObj == texUnit->CurrentTex[targetIndex]));
1252dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
1253dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      if (early_out) {
1254dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul         return;
1255dfda559b9867d70b70b99c0f3e751fd5930bdc01Brian Paul      }
12567f8000db8bd45bb95bda4a4f8535c49b8ef74254Ian Romanick   }
12577f8000db8bd45bb95bda4a4f8535c49b8ef74254Ian Romanick
12589e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   /* flush before changing binding */
1259cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1260cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell
12619e01b915f1243a3f551cb795b7124bd1e52ca15fBrian   /* Do the actual binding.  The refcount on the previously bound
12629e01b915f1243a3f551cb795b7124bd1e52ca15fBrian    * texture object will be decremented.  It'll be deleted if the
12639e01b915f1243a3f551cb795b7124bd1e52ca15fBrian    * count hits zero.
12649e01b915f1243a3f551cb795b7124bd1e52ca15fBrian    */
12659818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], newTexObj);
12669818734e0148510967ca9ee0d1aa8b196b509f02Brian Paul   ASSERT(texUnit->CurrentTex[targetIndex]);
1267afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1268afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   /* Pass BindTexture call to device driver */
12695e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen   if (ctx->Driver.BindTexture)
1270d6a0692f9dc055c5e5f0e7c806537ad24aa13709Brian Paul      ctx->Driver.BindTexture(ctx, target, newTexObj);
1271afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
1272afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1273f18fc687071a71a6f821a779a83b435f80d55b64Brian Paul
12746dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
12756dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Set texture priorities.
12766dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
12776dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of textures.
12786dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texName texture names.
12796dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param priorities corresponding texture priorities.
12806dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
12816dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glPrioritizeTextures().
12826dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
12836dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Looks up each texture in the hash, clamps the corresponding priority between
12846dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture.
1285afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1286c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY
1287fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,
1288fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul                          const GLclampf *priorities )
1289afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
1290fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1291afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   GLint i;
1292cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1293afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
12946d04725282f32cbd32acbc8b79294a2a056b2158Brian Paul   if (n < 0) {
129508836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" );
1296afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return;
1297afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
1298afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1299507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul   if (!priorities)
1300507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return;
1301507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul
13026d04725282f32cbd32acbc8b79294a2a056b2158Brian Paul   for (i = 0; i < n; i++) {
13036d04725282f32cbd32acbc8b79294a2a056b2158Brian Paul      if (texName[i] > 0) {
1304ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         struct gl_texture_object *t = _mesa_lookup_texture(ctx, texName[i]);
1305afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         if (t) {
1306afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg            t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );
1307afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         }
1308afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
1309afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
1310a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell
1311a96308c37db0bc0086a017d318bc3504aa5f0b1aKeith Whitwell   ctx->NewState |= _NEW_TEXTURE;
1312afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
1313afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
131476114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul
131576114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul
13166dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
13176dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * See if textures are loaded in texture memory.
13186dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13196dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param n number of textures to query.
13206dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texName array with the texture names.
13216dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param residences array which will hold the residence status.
13226dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13236dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \return GL_TRUE if all textures are resident and \p residences is left unchanged,
13246dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13252f88139145da99a695680c813ef5cc669eaef034Brian Paul * Note: we assume all textures are always resident
1326afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1327c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall BennettGLboolean GLAPIENTRY
1328bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul_mesa_AreTexturesResident(GLsizei n, const GLuint *texName,
1329bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul                          GLboolean *residences)
1330afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
1331fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1332bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   GLboolean allResident = GL_TRUE;
13332f88139145da99a695680c813ef5cc669eaef034Brian Paul   GLint i;
1334cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
1335afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1336bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   if (n < 0) {
133708836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)");
1338afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      return GL_FALSE;
1339afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
1340afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
1341507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul   if (!texName || !residences)
1342507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul      return GL_FALSE;
1343507d83e4cc0eb2fbc4a5ce3b87ed0b40634df5a8Brian Paul
13442f88139145da99a695680c813ef5cc669eaef034Brian Paul   /* We only do error checking on the texture names */
1345bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   for (i = 0; i < n; i++) {
1346afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      struct gl_texture_object *t;
1347bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul      if (texName[i] == 0) {
134824e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
1349afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg         return GL_FALSE;
1350afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
1351ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      t = _mesa_lookup_texture(ctx, texName[i]);
135224e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul      if (!t) {
135324e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
135424e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul         return GL_FALSE;
135524e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul      }
1356afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
135724e81fda4d3c55003294a818de7c0faf7ae1552dBrian Paul
1358bd0f7f42d6413577b78c342ab2f73b8d05c81d2fBrian Paul   return allResident;
1359afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
1360afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
136176114d23d1bcd5635b69d8536a8047cbf6c4c6e2Brian Paul
13626dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/**
13636dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * See if a name corresponds to a texture.
13646dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13656dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \param texture texture name.
13666dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13676dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE
13686dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * otherwise.
13696dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13706dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * \sa glIsTexture().
13716dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell *
13726dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell * Calls _mesa_HashLookup().
1373afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
1374c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall BennettGLboolean GLAPIENTRY
1375fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_IsTexture( GLuint texture )
1376afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
13773ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   struct gl_texture_object *t;
1378fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul   GET_CURRENT_CONTEXT(ctx);
1379cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
13803ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul
1381b756990b8407d67a15cf7f63683d50dd7f9e3a4eDaniel Borca   if (!texture)
13823ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul      return GL_FALSE;
13833ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul
1384ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   t = _mesa_lookup_texture(ctx, texture);
13853ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul
13863ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   /* IsTexture is true only after object has been bound once. */
13873ec0631e955cb79cf6009e391cd9b4f6a263b989Brian Paul   return t && t->Target;
1388afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
13896dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell
1390a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian
1391a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian/**
13923105fd760b8a6fc34438d51d36b65670810626a2Brian Paul * Simplest implementation of texture locking: grab the shared tex
13933105fd760b8a6fc34438d51d36b65670810626a2Brian Paul * mutex.  Examine the shared context state timestamp and if there has
13943105fd760b8a6fc34438d51d36b65670810626a2Brian Paul * been a change, set the appropriate bits in ctx->NewState.
13955ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell *
1396a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian * This is used to deal with synchronizing things when a texture object
1397a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian * is used/modified by different contexts (or threads) which are sharing
1398a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian * the texture.
1399a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian *
1400a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brian * See also _mesa_lock/unlock_texture() in teximage.h
14015ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell */
1402a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brianvoid
1403f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_lock_context_textures( struct gl_context *ctx )
14045ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell{
14055ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell   _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
14065ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
14075ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell   if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) {
14085ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell      ctx->NewState |= _NEW_TEXTURE;
14095ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell      ctx->TextureStateTimestamp = ctx->Shared->TextureStateStamp;
14105ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell   }
14115ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell}
14125ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
14135ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
1414a01ee8ff0bdc9b80907f2fe48ebf1618ce2ded92Brianvoid
1415f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_unlock_context_textures( struct gl_context *ctx )
14165ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell{
14175ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell   assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp);
14185ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell   _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
14195ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell}
14205ac93f86210eb5c2a8dee74ec19b0ecd54376863Keith Whitwell
142107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanickvoid GLAPIENTRY
142207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick_mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
142307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick                            GLint yoffset, GLint zoffset, GLsizei width,
142407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick                            GLsizei height, GLsizei depth)
142507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick{
142607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   struct gl_texture_object *t;
142707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   struct gl_texture_image *image;
142807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   GET_CURRENT_CONTEXT(ctx);
142907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
143007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   ASSERT_OUTSIDE_BEGIN_END(ctx);
143107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
143207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   t = invalidate_tex_image_error_check(ctx, texture, level,
143307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick                                        "glInvalidateTexSubImage");
143407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
143507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   /* The GL_ARB_invalidate_subdata spec says:
143607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *
143707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     "...the specified subregion must be between -<b> and <dim>+<b> where
143807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     <dim> is the size of the dimension of the texture image, and <b> is
143907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     the size of the border of that texture image, otherwise
144007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     INVALID_VALUE is generated (border is not applied to dimensions that
144107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    *     don't exist in a given texture target)."
144207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    */
144307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   image = t->Image[0][level];
144407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   if (image) {
144507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      int xBorder;
144607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      int yBorder;
144707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      int zBorder;
144807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      int imageWidth;
144907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      int imageHeight;
145007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      int imageDepth;
145107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
145207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      /* The GL_ARB_invalidate_subdata spec says:
145307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick       *
145407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick       *     "For texture targets that don't have certain dimensions, this
145507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick       *     command treats those dimensions as having a size of 1. For
145607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick       *     example, to invalidate a portion of a two-dimensional texture,
145707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick       *     the application would use <zoffset> equal to zero and <depth>
145807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick       *     equal to one."
145907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick       */
146007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      switch (t->Target) {
146107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_BUFFER:
146207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         xBorder = 0;
146307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         yBorder = 0;
146407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         zBorder = 0;
146507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageWidth = 1;
146607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageHeight = 1;
146707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageDepth = 1;
146807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         break;
146907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_1D:
147007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         xBorder = image->Border;
147107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         yBorder = 0;
147207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         zBorder = 0;
147307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageWidth = image->Width;
147407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageHeight = 1;
147507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageDepth = 1;
147607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         break;
147707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_1D_ARRAY:
147807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         xBorder = image->Border;
147907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         yBorder = 0;
148007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         zBorder = 0;
148107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageWidth = image->Width;
148207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageHeight = image->Height;
148307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageDepth = 1;
148407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         break;
148507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_2D:
148607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_CUBE_MAP:
148707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_RECTANGLE:
148807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_2D_MULTISAMPLE:
148907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         xBorder = image->Border;
149007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         yBorder = image->Border;
149107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         zBorder = 0;
149207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageWidth = image->Width;
149307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageHeight = image->Height;
149407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageDepth = 1;
149507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         break;
149607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_2D_ARRAY:
149707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_CUBE_MAP_ARRAY:
149807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         xBorder = image->Border;
149907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         yBorder = image->Border;
150007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         zBorder = 0;
150107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageWidth = image->Width;
150207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageHeight = image->Height;
150307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageDepth = image->Depth;
150407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         break;
150507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      case GL_TEXTURE_3D:
150607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         xBorder = image->Border;
150707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         yBorder = image->Border;
150807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         zBorder = image->Border;
150907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageWidth = image->Width;
151007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageHeight = image->Height;
151107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageDepth = image->Depth;
151207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         break;
151307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      default:
151407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         assert(!"Should not get here.");
151507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         xBorder = 0;
151607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         yBorder = 0;
151707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         zBorder = 0;
151807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageWidth = 0;
151907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageHeight = 0;
152007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         imageDepth = 0;
152107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         break;
152207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      }
152307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
152407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      if (xoffset < -xBorder) {
152507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(xoffset)");
152607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         return;
152707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      }
152807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
152907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      if (xoffset + width > imageWidth + xBorder) {
153007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         _mesa_error(ctx, GL_INVALID_VALUE,
153107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick                     "glInvalidateSubTexImage(xoffset+width)");
153207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         return;
153307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      }
153407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
153507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      if (yoffset < -yBorder) {
153607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(yoffset)");
153707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         return;
153807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      }
153907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
154007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      if (yoffset + height > imageHeight + yBorder) {
154107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         _mesa_error(ctx, GL_INVALID_VALUE,
154207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick                     "glInvalidateSubTexImage(yoffset+height)");
154307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         return;
154407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      }
154507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
154607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      if (zoffset < -zBorder) {
154707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         _mesa_error(ctx, GL_INVALID_VALUE,
154807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick                     "glInvalidateSubTexImage(zoffset)");
154907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         return;
155007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      }
155107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
155207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      if (zoffset + depth  > imageDepth + zBorder) {
155307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         _mesa_error(ctx, GL_INVALID_VALUE,
155407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick                     "glInvalidateSubTexImage(zoffset+depth)");
155507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick         return;
155607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick      }
155707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   }
155807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
155907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   /* We don't actually do anything for this yet.  Just return after
156007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    * validating the parameters and generating the required errors.
156107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    */
156207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   return;
156307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick}
156407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
156507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanickvoid GLAPIENTRY
156607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick_mesa_InvalidateTexImage(GLuint texture, GLint level)
156707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick{
156807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   GET_CURRENT_CONTEXT(ctx);
156907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
157007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   ASSERT_OUTSIDE_BEGIN_END(ctx);
157107e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
157207e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   invalidate_tex_image_error_check(ctx, texture, level,
157307e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick                                    "glInvalidateTexImage");
157407e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
157507e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   /* We don't actually do anything for this yet.  Just return after
157607e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    * validating the parameters and generating the required errors.
157707e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick    */
157807e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick   return;
157907e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick}
158007e12c49175e0bf23dbd8bdc3afd7aa79ccc7140Ian Romanick
15816dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell/*@}*/
1582