• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * \file texobj.c
3  * Texture object management.
4  */
5 
6 /*
7  * Mesa 3-D graphics library
8  *
9  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  * OTHER DEALINGS IN THE SOFTWARE.
28  */
29 
30 
31 #include <stdio.h>
32 #include "bufferobj.h"
33 #include "context.h"
34 #include "enums.h"
35 #include "fbobject.h"
36 #include "formats.h"
37 #include "hash.h"
38 #include "imports.h"
39 #include "macros.h"
40 #include "shaderimage.h"
41 #include "teximage.h"
42 #include "texobj.h"
43 #include "texstate.h"
44 #include "mtypes.h"
45 #include "program/prog_instruction.h"
46 #include "texturebindless.h"
47 
48 
49 
50 /**********************************************************************/
51 /** \name Internal functions */
52 /*@{*/
53 
54 /**
55  * This function checks for all valid combinations of Min and Mag filters for
56  * Float types, when extensions like OES_texture_float and
57  * OES_texture_float_linear are supported. OES_texture_float mentions support
58  * for NEAREST, NEAREST_MIPMAP_NEAREST magnification and minification filters.
59  * Mag filters like LINEAR and min filters like NEAREST_MIPMAP_LINEAR,
60  * LINEAR_MIPMAP_NEAREST and LINEAR_MIPMAP_LINEAR are only valid in case
61  * OES_texture_float_linear is supported.
62  *
63  * Returns true in case the filter is valid for given Float type else false.
64  */
65 static bool
valid_filter_for_float(const struct gl_context * ctx,const struct gl_texture_object * obj)66 valid_filter_for_float(const struct gl_context *ctx,
67                        const struct gl_texture_object *obj)
68 {
69    switch (obj->Sampler.MagFilter) {
70    case GL_LINEAR:
71       if (obj->_IsHalfFloat && !ctx->Extensions.OES_texture_half_float_linear) {
72          return false;
73       } else if (obj->_IsFloat && !ctx->Extensions.OES_texture_float_linear) {
74          return false;
75       }
76    case GL_NEAREST:
77    case GL_NEAREST_MIPMAP_NEAREST:
78       break;
79    default:
80       unreachable("Invalid mag filter");
81    }
82 
83    switch (obj->Sampler.MinFilter) {
84    case GL_LINEAR:
85    case GL_NEAREST_MIPMAP_LINEAR:
86    case GL_LINEAR_MIPMAP_NEAREST:
87    case GL_LINEAR_MIPMAP_LINEAR:
88       if (obj->_IsHalfFloat && !ctx->Extensions.OES_texture_half_float_linear) {
89          return false;
90       } else if (obj->_IsFloat && !ctx->Extensions.OES_texture_float_linear) {
91          return false;
92       }
93    case GL_NEAREST:
94    case GL_NEAREST_MIPMAP_NEAREST:
95       break;
96    default:
97       unreachable("Invalid min filter");
98    }
99 
100    return true;
101 }
102 
103 /**
104  * Return the gl_texture_object for a given ID.
105  */
106 struct gl_texture_object *
_mesa_lookup_texture(struct gl_context * ctx,GLuint id)107 _mesa_lookup_texture(struct gl_context *ctx, GLuint id)
108 {
109    return (struct gl_texture_object *)
110       _mesa_HashLookup(ctx->Shared->TexObjects, id);
111 }
112 
113 /**
114  * Wrapper around _mesa_lookup_texture that throws GL_INVALID_OPERATION if id
115  * is not in the hash table. After calling _mesa_error, it returns NULL.
116  */
117 struct gl_texture_object *
_mesa_lookup_texture_err(struct gl_context * ctx,GLuint id,const char * func)118 _mesa_lookup_texture_err(struct gl_context *ctx, GLuint id, const char* func)
119 {
120    struct gl_texture_object *texObj = NULL;
121 
122    if (id > 0)
123       texObj = _mesa_lookup_texture(ctx, id); /* Returns NULL if not found. */
124 
125    if (!texObj)
126       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture)", func);
127 
128    return texObj;
129 }
130 
131 
132 struct gl_texture_object *
_mesa_lookup_texture_locked(struct gl_context * ctx,GLuint id)133 _mesa_lookup_texture_locked(struct gl_context *ctx, GLuint id)
134 {
135    return (struct gl_texture_object *)
136       _mesa_HashLookupLocked(ctx->Shared->TexObjects, id);
137 }
138 
139 /**
140  * Return a pointer to the current texture object for the given target
141  * on the current texture unit.
142  * Note: all <target> error checking should have been done by this point.
143  */
144 struct gl_texture_object *
_mesa_get_current_tex_object(struct gl_context * ctx,GLenum target)145 _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target)
146 {
147    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
148    const GLboolean arrayTex = ctx->Extensions.EXT_texture_array;
149 
150    switch (target) {
151       case GL_TEXTURE_1D:
152          return texUnit->CurrentTex[TEXTURE_1D_INDEX];
153       case GL_PROXY_TEXTURE_1D:
154          return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
155       case GL_TEXTURE_2D:
156          return texUnit->CurrentTex[TEXTURE_2D_INDEX];
157       case GL_PROXY_TEXTURE_2D:
158          return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
159       case GL_TEXTURE_3D:
160          return texUnit->CurrentTex[TEXTURE_3D_INDEX];
161       case GL_PROXY_TEXTURE_3D:
162          return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
163       case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
164       case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
165       case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
166       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
167       case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
168       case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
169       case GL_TEXTURE_CUBE_MAP:
170          return ctx->Extensions.ARB_texture_cube_map
171                 ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL;
172       case GL_PROXY_TEXTURE_CUBE_MAP:
173          return ctx->Extensions.ARB_texture_cube_map
174                 ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL;
175       case GL_TEXTURE_CUBE_MAP_ARRAY:
176          return _mesa_has_texture_cube_map_array(ctx)
177                 ? texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL;
178       case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
179          return _mesa_has_texture_cube_map_array(ctx)
180                 ? ctx->Texture.ProxyTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL;
181       case GL_TEXTURE_RECTANGLE_NV:
182          return ctx->Extensions.NV_texture_rectangle
183                 ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL;
184       case GL_PROXY_TEXTURE_RECTANGLE_NV:
185          return ctx->Extensions.NV_texture_rectangle
186                 ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL;
187       case GL_TEXTURE_1D_ARRAY_EXT:
188          return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
189       case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
190          return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
191       case GL_TEXTURE_2D_ARRAY_EXT:
192          return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
193       case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
194          return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
195       case GL_TEXTURE_BUFFER:
196          return (_mesa_has_ARB_texture_buffer_object(ctx) ||
197                  _mesa_has_OES_texture_buffer(ctx)) ?
198                 texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL;
199       case GL_TEXTURE_EXTERNAL_OES:
200          return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external
201             ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL;
202       case GL_TEXTURE_2D_MULTISAMPLE:
203          return ctx->Extensions.ARB_texture_multisample
204             ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL;
205       case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
206          return ctx->Extensions.ARB_texture_multisample
207             ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL;
208       case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
209          return ctx->Extensions.ARB_texture_multisample
210             ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL;
211       case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
212          return ctx->Extensions.ARB_texture_multisample
213             ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL;
214       default:
215          _mesa_problem(NULL, "bad target in _mesa_get_current_tex_object()");
216          return NULL;
217    }
218 }
219 
220 
221 /**
222  * Allocate and initialize a new texture object.  But don't put it into the
223  * texture object hash table.
224  *
225  * Called via ctx->Driver.NewTextureObject, unless overridden by a device
226  * driver.
227  *
228  * \param shared the shared GL state structure to contain the texture object
229  * \param name integer name for the texture object
230  * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
231  * GL_TEXTURE_CUBE_MAP or GL_TEXTURE_RECTANGLE_NV.  zero is ok for the sake
232  * of GenTextures()
233  *
234  * \return pointer to new texture object.
235  */
236 struct gl_texture_object *
_mesa_new_texture_object(struct gl_context * ctx,GLuint name,GLenum target)237 _mesa_new_texture_object(struct gl_context *ctx, GLuint name, GLenum target)
238 {
239    struct gl_texture_object *obj;
240 
241    obj = MALLOC_STRUCT(gl_texture_object);
242    if (!obj)
243       return NULL;
244 
245    _mesa_initialize_texture_object(ctx, obj, name, target);
246    return obj;
247 }
248 
249 
250 /**
251  * Initialize a new texture object to default values.
252  * \param obj  the texture object
253  * \param name  the texture name
254  * \param target  the texture target
255  */
256 void
_mesa_initialize_texture_object(struct gl_context * ctx,struct gl_texture_object * obj,GLuint name,GLenum target)257 _mesa_initialize_texture_object( struct gl_context *ctx,
258                                  struct gl_texture_object *obj,
259                                  GLuint name, GLenum target )
260 {
261    assert(target == 0 ||
262           target == GL_TEXTURE_1D ||
263           target == GL_TEXTURE_2D ||
264           target == GL_TEXTURE_3D ||
265           target == GL_TEXTURE_CUBE_MAP ||
266           target == GL_TEXTURE_RECTANGLE_NV ||
267           target == GL_TEXTURE_1D_ARRAY_EXT ||
268           target == GL_TEXTURE_2D_ARRAY_EXT ||
269           target == GL_TEXTURE_EXTERNAL_OES ||
270           target == GL_TEXTURE_CUBE_MAP_ARRAY ||
271           target == GL_TEXTURE_BUFFER ||
272           target == GL_TEXTURE_2D_MULTISAMPLE ||
273           target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
274 
275    memset(obj, 0, sizeof(*obj));
276    /* init the non-zero fields */
277    simple_mtx_init(&obj->Mutex, mtx_plain);
278    obj->RefCount = 1;
279    obj->Name = name;
280    obj->Target = target;
281    if (target != 0) {
282       obj->TargetIndex = _mesa_tex_target_to_index(ctx, target);
283    }
284    else {
285       obj->TargetIndex = NUM_TEXTURE_TARGETS; /* invalid/error value */
286    }
287    obj->Priority = 1.0F;
288    obj->BaseLevel = 0;
289    obj->MaxLevel = 1000;
290 
291    /* must be one; no support for (YUV) planes in separate buffers */
292    obj->RequiredTextureImageUnits = 1;
293 
294    /* sampler state */
295    if (target == GL_TEXTURE_RECTANGLE_NV ||
296        target == GL_TEXTURE_EXTERNAL_OES) {
297       obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
298       obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
299       obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
300       obj->Sampler.MinFilter = GL_LINEAR;
301    }
302    else {
303       obj->Sampler.WrapS = GL_REPEAT;
304       obj->Sampler.WrapT = GL_REPEAT;
305       obj->Sampler.WrapR = GL_REPEAT;
306       obj->Sampler.MinFilter = GL_NEAREST_MIPMAP_LINEAR;
307    }
308    obj->Sampler.MagFilter = GL_LINEAR;
309    obj->Sampler.MinLod = -1000.0;
310    obj->Sampler.MaxLod = 1000.0;
311    obj->Sampler.LodBias = 0.0;
312    obj->Sampler.MaxAnisotropy = 1.0;
313    obj->Sampler.CompareMode = GL_NONE;         /* ARB_shadow */
314    obj->Sampler.CompareFunc = GL_LEQUAL;       /* ARB_shadow */
315    obj->DepthMode = ctx->API == API_OPENGL_CORE ? GL_RED : GL_LUMINANCE;
316    obj->StencilSampling = false;
317    obj->Sampler.CubeMapSeamless = GL_FALSE;
318    obj->Sampler.HandleAllocated = GL_FALSE;
319    obj->Swizzle[0] = GL_RED;
320    obj->Swizzle[1] = GL_GREEN;
321    obj->Swizzle[2] = GL_BLUE;
322    obj->Swizzle[3] = GL_ALPHA;
323    obj->_Swizzle = SWIZZLE_NOOP;
324    obj->Sampler.sRGBDecode = GL_DECODE_EXT;
325    obj->BufferObjectFormat = GL_R8;
326    obj->_BufferObjectFormat = MESA_FORMAT_R_UNORM8;
327    obj->ImageFormatCompatibilityType = GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE;
328 
329    /* GL_ARB_bindless_texture */
330    _mesa_init_texture_handles(obj);
331 }
332 
333 
334 /**
335  * Some texture initialization can't be finished until we know which
336  * target it's getting bound to (GL_TEXTURE_1D/2D/etc).
337  */
338 static void
finish_texture_init(struct gl_context * ctx,GLenum target,struct gl_texture_object * obj,int targetIndex)339 finish_texture_init(struct gl_context *ctx, GLenum target,
340                     struct gl_texture_object *obj, int targetIndex)
341 {
342    GLenum filter = GL_LINEAR;
343    assert(obj->Target == 0);
344 
345    obj->Target = target;
346    obj->TargetIndex = targetIndex;
347    assert(obj->TargetIndex < NUM_TEXTURE_TARGETS);
348 
349    switch (target) {
350       case GL_TEXTURE_2D_MULTISAMPLE:
351       case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
352          filter = GL_NEAREST;
353          /* fallthrough */
354 
355       case GL_TEXTURE_RECTANGLE_NV:
356       case GL_TEXTURE_EXTERNAL_OES:
357          /* have to init wrap and filter state here - kind of klunky */
358          obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
359          obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
360          obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
361          obj->Sampler.MinFilter = filter;
362          obj->Sampler.MagFilter = filter;
363          if (ctx->Driver.TexParameter) {
364             /* XXX we probably don't need to make all these calls */
365             ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_S);
366             ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_T);
367             ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_R);
368             ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_MIN_FILTER);
369             ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_MAG_FILTER);
370          }
371          break;
372 
373       default:
374          /* nothing needs done */
375          break;
376    }
377 }
378 
379 
380 /**
381  * Deallocate a texture object struct.  It should have already been
382  * removed from the texture object pool.
383  * Called via ctx->Driver.DeleteTexture() if not overriden by a driver.
384  *
385  * \param shared the shared GL state to which the object belongs.
386  * \param texObj the texture object to delete.
387  */
388 void
_mesa_delete_texture_object(struct gl_context * ctx,struct gl_texture_object * texObj)389 _mesa_delete_texture_object(struct gl_context *ctx,
390                             struct gl_texture_object *texObj)
391 {
392    GLuint i, face;
393 
394    /* Set Target to an invalid value.  With some assertions elsewhere
395     * we can try to detect possible use of deleted textures.
396     */
397    texObj->Target = 0x99;
398 
399    /* free the texture images */
400    for (face = 0; face < 6; face++) {
401       for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
402          if (texObj->Image[face][i]) {
403             ctx->Driver.DeleteTextureImage(ctx, texObj->Image[face][i]);
404          }
405       }
406    }
407 
408    /* Delete all texture/image handles. */
409    _mesa_delete_texture_handles(ctx, texObj);
410 
411    _mesa_reference_buffer_object(ctx, &texObj->BufferObject, NULL);
412 
413    /* destroy the mutex -- it may have allocated memory (eg on bsd) */
414    simple_mtx_destroy(&texObj->Mutex);
415 
416    free(texObj->Label);
417 
418    /* free this object */
419    free(texObj);
420 }
421 
422 
423 /**
424  * Copy texture object state from one texture object to another.
425  * Use for glPush/PopAttrib.
426  *
427  * \param dest destination texture object.
428  * \param src source texture object.
429  */
430 void
_mesa_copy_texture_object(struct gl_texture_object * dest,const struct gl_texture_object * src)431 _mesa_copy_texture_object( struct gl_texture_object *dest,
432                            const struct gl_texture_object *src )
433 {
434    dest->Target = src->Target;
435    dest->TargetIndex = src->TargetIndex;
436    dest->Name = src->Name;
437    dest->Priority = src->Priority;
438    dest->Sampler.BorderColor.f[0] = src->Sampler.BorderColor.f[0];
439    dest->Sampler.BorderColor.f[1] = src->Sampler.BorderColor.f[1];
440    dest->Sampler.BorderColor.f[2] = src->Sampler.BorderColor.f[2];
441    dest->Sampler.BorderColor.f[3] = src->Sampler.BorderColor.f[3];
442    dest->Sampler.WrapS = src->Sampler.WrapS;
443    dest->Sampler.WrapT = src->Sampler.WrapT;
444    dest->Sampler.WrapR = src->Sampler.WrapR;
445    dest->Sampler.MinFilter = src->Sampler.MinFilter;
446    dest->Sampler.MagFilter = src->Sampler.MagFilter;
447    dest->Sampler.MinLod = src->Sampler.MinLod;
448    dest->Sampler.MaxLod = src->Sampler.MaxLod;
449    dest->Sampler.LodBias = src->Sampler.LodBias;
450    dest->BaseLevel = src->BaseLevel;
451    dest->MaxLevel = src->MaxLevel;
452    dest->Sampler.MaxAnisotropy = src->Sampler.MaxAnisotropy;
453    dest->Sampler.CompareMode = src->Sampler.CompareMode;
454    dest->Sampler.CompareFunc = src->Sampler.CompareFunc;
455    dest->Sampler.CubeMapSeamless = src->Sampler.CubeMapSeamless;
456    dest->DepthMode = src->DepthMode;
457    dest->StencilSampling = src->StencilSampling;
458    dest->Sampler.sRGBDecode = src->Sampler.sRGBDecode;
459    dest->_MaxLevel = src->_MaxLevel;
460    dest->_MaxLambda = src->_MaxLambda;
461    dest->GenerateMipmap = src->GenerateMipmap;
462    dest->_BaseComplete = src->_BaseComplete;
463    dest->_MipmapComplete = src->_MipmapComplete;
464    COPY_4V(dest->Swizzle, src->Swizzle);
465    dest->_Swizzle = src->_Swizzle;
466    dest->_IsHalfFloat = src->_IsHalfFloat;
467    dest->_IsFloat = src->_IsFloat;
468 
469    dest->RequiredTextureImageUnits = src->RequiredTextureImageUnits;
470 }
471 
472 
473 /**
474  * Free all texture images of the given texture objectm, except for
475  * \p retainTexImage.
476  *
477  * \param ctx GL context.
478  * \param texObj texture object.
479  * \param retainTexImage a texture image that will \em not be freed.
480  *
481  * \sa _mesa_clear_texture_image().
482  */
483 void
_mesa_clear_texture_object(struct gl_context * ctx,struct gl_texture_object * texObj,struct gl_texture_image * retainTexImage)484 _mesa_clear_texture_object(struct gl_context *ctx,
485                            struct gl_texture_object *texObj,
486                            struct gl_texture_image *retainTexImage)
487 {
488    GLuint i, j;
489 
490    if (texObj->Target == 0)
491       return;
492 
493    for (i = 0; i < MAX_FACES; i++) {
494       for (j = 0; j < MAX_TEXTURE_LEVELS; j++) {
495          struct gl_texture_image *texImage = texObj->Image[i][j];
496          if (texImage && texImage != retainTexImage)
497             _mesa_clear_texture_image(ctx, texImage);
498       }
499    }
500 }
501 
502 
503 /**
504  * Check if the given texture object is valid by examining its Target field.
505  * For debugging only.
506  */
507 static GLboolean
valid_texture_object(const struct gl_texture_object * tex)508 valid_texture_object(const struct gl_texture_object *tex)
509 {
510    switch (tex->Target) {
511    case 0:
512    case GL_TEXTURE_1D:
513    case GL_TEXTURE_2D:
514    case GL_TEXTURE_3D:
515    case GL_TEXTURE_CUBE_MAP:
516    case GL_TEXTURE_RECTANGLE_NV:
517    case GL_TEXTURE_1D_ARRAY_EXT:
518    case GL_TEXTURE_2D_ARRAY_EXT:
519    case GL_TEXTURE_BUFFER:
520    case GL_TEXTURE_EXTERNAL_OES:
521    case GL_TEXTURE_CUBE_MAP_ARRAY:
522    case GL_TEXTURE_2D_MULTISAMPLE:
523    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
524       return GL_TRUE;
525    case 0x99:
526       _mesa_problem(NULL, "invalid reference to a deleted texture object");
527       return GL_FALSE;
528    default:
529       _mesa_problem(NULL, "invalid texture object Target 0x%x, Id = %u",
530                     tex->Target, tex->Name);
531       return GL_FALSE;
532    }
533 }
534 
535 
536 /**
537  * Reference (or unreference) a texture object.
538  * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero).
539  * If 'tex' is non-null, increment its refcount.
540  * This is normally only called from the _mesa_reference_texobj() macro
541  * when there's a real pointer change.
542  */
543 void
_mesa_reference_texobj_(struct gl_texture_object ** ptr,struct gl_texture_object * tex)544 _mesa_reference_texobj_(struct gl_texture_object **ptr,
545                         struct gl_texture_object *tex)
546 {
547    assert(ptr);
548 
549    if (*ptr) {
550       /* Unreference the old texture */
551       GLboolean deleteFlag = GL_FALSE;
552       struct gl_texture_object *oldTex = *ptr;
553 
554       assert(valid_texture_object(oldTex));
555       (void) valid_texture_object; /* silence warning in release builds */
556 
557       simple_mtx_lock(&oldTex->Mutex);
558       assert(oldTex->RefCount > 0);
559       oldTex->RefCount--;
560 
561       deleteFlag = (oldTex->RefCount == 0);
562       simple_mtx_unlock(&oldTex->Mutex);
563 
564       if (deleteFlag) {
565          /* Passing in the context drastically changes the driver code for
566           * framebuffer deletion.
567           */
568          GET_CURRENT_CONTEXT(ctx);
569          if (ctx)
570             ctx->Driver.DeleteTexture(ctx, oldTex);
571          else
572             _mesa_problem(NULL, "Unable to delete texture, no context");
573       }
574 
575       *ptr = NULL;
576    }
577    assert(!*ptr);
578 
579    if (tex) {
580       /* reference new texture */
581       assert(valid_texture_object(tex));
582       simple_mtx_lock(&tex->Mutex);
583       assert(tex->RefCount > 0);
584 
585       tex->RefCount++;
586       *ptr = tex;
587       simple_mtx_unlock(&tex->Mutex);
588    }
589 }
590 
591 
592 enum base_mipmap { BASE, MIPMAP };
593 
594 
595 /**
596  * Mark a texture object as incomplete.  There are actually three kinds of
597  * (in)completeness:
598  * 1. "base incomplete": the base level of the texture is invalid so no
599  *    texturing is possible.
600  * 2. "mipmap incomplete": a non-base level of the texture is invalid so
601  *    mipmap filtering isn't possible, but non-mipmap filtering is.
602  * 3. "texture incompleteness": some combination of texture state and
603  *    sampler state renders the texture incomplete.
604  *
605  * \param t  texture object
606  * \param bm  either BASE or MIPMAP to indicate what's incomplete
607  * \param fmt...  string describing why it's incomplete (for debugging).
608  */
609 static void
incomplete(struct gl_texture_object * t,enum base_mipmap bm,const char * fmt,...)610 incomplete(struct gl_texture_object *t, enum base_mipmap bm,
611            const char *fmt, ...)
612 {
613    if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_TEXTURE) {
614       va_list args;
615       char s[100];
616 
617       va_start(args, fmt);
618       vsnprintf(s, sizeof(s), fmt, args);
619       va_end(args);
620 
621       _mesa_debug(NULL, "Texture Obj %d incomplete because: %s\n", t->Name, s);
622    }
623 
624    if (bm == BASE)
625       t->_BaseComplete = GL_FALSE;
626    t->_MipmapComplete = GL_FALSE;
627 }
628 
629 
630 /**
631  * Examine a texture object to determine if it is complete.
632  *
633  * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE
634  * accordingly.
635  *
636  * \param ctx GL context.
637  * \param t texture object.
638  *
639  * According to the texture target, verifies that each of the mipmaps is
640  * present and has the expected size.
641  */
642 void
_mesa_test_texobj_completeness(const struct gl_context * ctx,struct gl_texture_object * t)643 _mesa_test_texobj_completeness( const struct gl_context *ctx,
644                                 struct gl_texture_object *t )
645 {
646    const GLint baseLevel = t->BaseLevel;
647    const struct gl_texture_image *baseImage;
648    GLint maxLevels = 0;
649 
650    /* We'll set these to FALSE if tests fail below */
651    t->_BaseComplete = GL_TRUE;
652    t->_MipmapComplete = GL_TRUE;
653 
654    if (t->Target == GL_TEXTURE_BUFFER) {
655       /* Buffer textures are always considered complete.  The obvious case where
656        * they would be incomplete (no BO attached) is actually specced to be
657        * undefined rendering results.
658        */
659       return;
660    }
661 
662    /* Detect cases where the application set the base level to an invalid
663     * value.
664     */
665    if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) {
666       incomplete(t, BASE, "base level = %d is invalid", baseLevel);
667       return;
668    }
669 
670    if (t->MaxLevel < baseLevel) {
671       incomplete(t, MIPMAP, "MAX_LEVEL (%d) < BASE_LEVEL (%d)",
672 		 t->MaxLevel, baseLevel);
673       return;
674    }
675 
676    baseImage = t->Image[0][baseLevel];
677 
678    /* Always need the base level image */
679    if (!baseImage) {
680       incomplete(t, BASE, "Image[baseLevel=%d] == NULL", baseLevel);
681       return;
682    }
683 
684    /* Check width/height/depth for zero */
685    if (baseImage->Width == 0 ||
686        baseImage->Height == 0 ||
687        baseImage->Depth == 0) {
688       incomplete(t, BASE, "texture width or height or depth = 0");
689       return;
690    }
691 
692    /* Check if the texture values are integer */
693    {
694       GLenum datatype = _mesa_get_format_datatype(baseImage->TexFormat);
695       t->_IsIntegerFormat = datatype == GL_INT || datatype == GL_UNSIGNED_INT;
696    }
697 
698    /* Check if the texture type is Float or HalfFloatOES and ensure Min and Mag
699     * filters are supported in this case.
700     */
701    if (_mesa_is_gles(ctx) && !valid_filter_for_float(ctx, t)) {
702       incomplete(t, BASE, "Filter is not supported with Float types.");
703       return;
704    }
705 
706    /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the
707     * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state).
708     */
709    switch (t->Target) {
710    case GL_TEXTURE_1D:
711    case GL_TEXTURE_1D_ARRAY_EXT:
712       maxLevels = ctx->Const.MaxTextureLevels;
713       break;
714    case GL_TEXTURE_2D:
715    case GL_TEXTURE_2D_ARRAY_EXT:
716       maxLevels = ctx->Const.MaxTextureLevels;
717       break;
718    case GL_TEXTURE_3D:
719       maxLevels = ctx->Const.Max3DTextureLevels;
720       break;
721    case GL_TEXTURE_CUBE_MAP:
722    case GL_TEXTURE_CUBE_MAP_ARRAY:
723       maxLevels = ctx->Const.MaxCubeTextureLevels;
724       break;
725    case GL_TEXTURE_RECTANGLE_NV:
726    case GL_TEXTURE_BUFFER:
727    case GL_TEXTURE_EXTERNAL_OES:
728    case GL_TEXTURE_2D_MULTISAMPLE:
729    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
730       maxLevels = 1;  /* no mipmapping */
731       break;
732    default:
733       _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness");
734       return;
735    }
736 
737    assert(maxLevels > 0);
738 
739    t->_MaxLevel = MIN3(t->MaxLevel,
740                        /* 'p' in the GL spec */
741                        (int) (baseLevel + baseImage->MaxNumLevels - 1),
742                        /* 'q' in the GL spec */
743                        maxLevels - 1);
744 
745    if (t->Immutable) {
746       /* Adjust max level for views: the data store may have more levels than
747        * the view exposes.
748        */
749       t->_MaxLevel = MIN2(t->_MaxLevel, t->NumLevels - 1);
750    }
751 
752    /* Compute _MaxLambda = q - p in the spec used during mipmapping */
753    t->_MaxLambda = (GLfloat) (t->_MaxLevel - baseLevel);
754 
755    if (t->Immutable) {
756       /* This texture object was created with glTexStorage1/2/3D() so we
757        * know that all the mipmap levels are the right size and all cube
758        * map faces are the same size.
759        * We don't need to do any of the additional checks below.
760        */
761       return;
762    }
763 
764    if (t->Target == GL_TEXTURE_CUBE_MAP) {
765       /* Make sure that all six cube map level 0 images are the same size and
766        * format.
767        * Note:  we know that the image's width==height (we enforce that
768        * at glTexImage time) so we only need to test the width here.
769        */
770       GLuint face;
771       assert(baseImage->Width2 == baseImage->Height);
772       for (face = 1; face < 6; face++) {
773          assert(t->Image[face][baseLevel] == NULL ||
774                 t->Image[face][baseLevel]->Width2 ==
775                 t->Image[face][baseLevel]->Height2);
776          if (t->Image[face][baseLevel] == NULL ||
777              t->Image[face][baseLevel]->Width2 != baseImage->Width2) {
778             incomplete(t, BASE, "Cube face missing or mismatched size");
779             return;
780          }
781          if (t->Image[face][baseLevel]->InternalFormat !=
782              baseImage->InternalFormat) {
783             incomplete(t, BASE, "Cube face format mismatch");
784             return;
785          }
786          if (t->Image[face][baseLevel]->Border != baseImage->Border) {
787             incomplete(t, BASE, "Cube face border size mismatch");
788             return;
789          }
790       }
791    }
792 
793    /*
794     * Do mipmap consistency checking.
795     * Note: we don't care about the current texture sampler state here.
796     * To determine texture completeness we'll either look at _BaseComplete
797     * or _MipmapComplete depending on the current minification filter mode.
798     */
799    {
800       GLint i;
801       const GLint minLevel = baseLevel;
802       const GLint maxLevel = t->_MaxLevel;
803       const GLuint numFaces = _mesa_num_tex_faces(t->Target);
804       GLuint width, height, depth, face;
805 
806       if (minLevel > maxLevel) {
807          incomplete(t, MIPMAP, "minLevel > maxLevel");
808          return;
809       }
810 
811       /* Get the base image's dimensions */
812       width = baseImage->Width2;
813       height = baseImage->Height2;
814       depth = baseImage->Depth2;
815 
816       /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL,
817        * MULTISAMPLE and MULTISAMPLE_ARRAY textures
818        */
819       for (i = baseLevel + 1; i < maxLevels; i++) {
820          /* Compute the expected size of image at level[i] */
821          if (width > 1) {
822             width /= 2;
823          }
824          if (height > 1 && t->Target != GL_TEXTURE_1D_ARRAY) {
825             height /= 2;
826          }
827          if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY
828              && t->Target != GL_TEXTURE_CUBE_MAP_ARRAY) {
829             depth /= 2;
830          }
831 
832          /* loop over cube faces (or single face otherwise) */
833          for (face = 0; face < numFaces; face++) {
834             if (i >= minLevel && i <= maxLevel) {
835                const struct gl_texture_image *img = t->Image[face][i];
836 
837                if (!img) {
838                   incomplete(t, MIPMAP, "TexImage[%d] is missing", i);
839                   return;
840                }
841                if (img->InternalFormat != baseImage->InternalFormat) {
842                   incomplete(t, MIPMAP, "Format[i] != Format[baseLevel]");
843                   return;
844                }
845                if (img->Border != baseImage->Border) {
846                   incomplete(t, MIPMAP, "Border[i] != Border[baseLevel]");
847                   return;
848                }
849                if (img->Width2 != width) {
850                   incomplete(t, MIPMAP, "TexImage[%d] bad width %u", i,
851                              img->Width2);
852                   return;
853                }
854                if (img->Height2 != height) {
855                   incomplete(t, MIPMAP, "TexImage[%d] bad height %u", i,
856                              img->Height2);
857                   return;
858                }
859                if (img->Depth2 != depth) {
860                   incomplete(t, MIPMAP, "TexImage[%d] bad depth %u", i,
861                              img->Depth2);
862                   return;
863                }
864             }
865          }
866 
867          if (width == 1 && height == 1 && depth == 1) {
868             return;  /* found smallest needed mipmap, all done! */
869          }
870       }
871    }
872 }
873 
874 
875 GLboolean
_mesa_cube_level_complete(const struct gl_texture_object * texObj,const GLint level)876 _mesa_cube_level_complete(const struct gl_texture_object *texObj,
877                           const GLint level)
878 {
879    const struct gl_texture_image *img0, *img;
880    GLuint face;
881 
882    if (texObj->Target != GL_TEXTURE_CUBE_MAP)
883       return GL_FALSE;
884 
885    if ((level < 0) || (level >= MAX_TEXTURE_LEVELS))
886       return GL_FALSE;
887 
888    /* check first face */
889    img0 = texObj->Image[0][level];
890    if (!img0 ||
891        img0->Width < 1 ||
892        img0->Width != img0->Height)
893       return GL_FALSE;
894 
895    /* check remaining faces vs. first face */
896    for (face = 1; face < 6; face++) {
897       img = texObj->Image[face][level];
898       if (!img ||
899           img->Width != img0->Width ||
900           img->Height != img0->Height ||
901           img->TexFormat != img0->TexFormat)
902          return GL_FALSE;
903    }
904 
905    return GL_TRUE;
906 }
907 
908 /**
909  * Check if the given cube map texture is "cube complete" as defined in
910  * the OpenGL specification.
911  */
912 GLboolean
_mesa_cube_complete(const struct gl_texture_object * texObj)913 _mesa_cube_complete(const struct gl_texture_object *texObj)
914 {
915    return _mesa_cube_level_complete(texObj, texObj->BaseLevel);
916 }
917 
918 /**
919  * Mark a texture object dirty.  It forces the object to be incomplete
920  * and forces the context to re-validate its state.
921  *
922  * \param ctx GL context.
923  * \param texObj texture object.
924  */
925 void
_mesa_dirty_texobj(struct gl_context * ctx,struct gl_texture_object * texObj)926 _mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj)
927 {
928    texObj->_BaseComplete = GL_FALSE;
929    texObj->_MipmapComplete = GL_FALSE;
930    ctx->NewState |= _NEW_TEXTURE_OBJECT;
931 }
932 
933 
934 /**
935  * Return pointer to a default/fallback texture of the given type/target.
936  * The texture is an RGBA texture with all texels = (0,0,0,1).
937  * That's the value a GLSL sampler should get when sampling from an
938  * incomplete texture.
939  */
940 struct gl_texture_object *
_mesa_get_fallback_texture(struct gl_context * ctx,gl_texture_index tex)941 _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
942 {
943    if (!ctx->Shared->FallbackTex[tex]) {
944       /* create fallback texture now */
945       const GLsizei width = 1, height = 1;
946       GLsizei depth = 1;
947       GLubyte texel[24];
948       struct gl_texture_object *texObj;
949       struct gl_texture_image *texImage;
950       mesa_format texFormat;
951       GLuint dims, face, numFaces = 1;
952       GLenum target;
953 
954       for (face = 0; face < 6; face++) {
955          texel[4*face + 0] =
956          texel[4*face + 1] =
957          texel[4*face + 2] = 0x0;
958          texel[4*face + 3] = 0xff;
959       }
960 
961       switch (tex) {
962       case TEXTURE_2D_ARRAY_INDEX:
963          dims = 3;
964          target = GL_TEXTURE_2D_ARRAY;
965          break;
966       case TEXTURE_1D_ARRAY_INDEX:
967          dims = 2;
968          target = GL_TEXTURE_1D_ARRAY;
969          break;
970       case TEXTURE_CUBE_INDEX:
971          dims = 2;
972          target = GL_TEXTURE_CUBE_MAP;
973          numFaces = 6;
974          break;
975       case TEXTURE_3D_INDEX:
976          dims = 3;
977          target = GL_TEXTURE_3D;
978          break;
979       case TEXTURE_RECT_INDEX:
980          dims = 2;
981          target = GL_TEXTURE_RECTANGLE;
982          break;
983       case TEXTURE_2D_INDEX:
984          dims = 2;
985          target = GL_TEXTURE_2D;
986          break;
987       case TEXTURE_1D_INDEX:
988          dims = 1;
989          target = GL_TEXTURE_1D;
990          break;
991       case TEXTURE_BUFFER_INDEX:
992          dims = 0;
993          target = GL_TEXTURE_BUFFER;
994          break;
995       case TEXTURE_CUBE_ARRAY_INDEX:
996          dims = 3;
997          target = GL_TEXTURE_CUBE_MAP_ARRAY;
998          depth = 6;
999          break;
1000       case TEXTURE_EXTERNAL_INDEX:
1001          dims = 2;
1002          target = GL_TEXTURE_EXTERNAL_OES;
1003          break;
1004       case TEXTURE_2D_MULTISAMPLE_INDEX:
1005          dims = 2;
1006          target = GL_TEXTURE_2D_MULTISAMPLE;
1007          break;
1008       case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX:
1009          dims = 3;
1010          target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
1011          break;
1012       default:
1013          /* no-op */
1014          return NULL;
1015       }
1016 
1017       /* create texture object */
1018       texObj = ctx->Driver.NewTextureObject(ctx, 0, target);
1019       if (!texObj)
1020          return NULL;
1021 
1022       assert(texObj->RefCount == 1);
1023       texObj->Sampler.MinFilter = GL_NEAREST;
1024       texObj->Sampler.MagFilter = GL_NEAREST;
1025 
1026       texFormat = ctx->Driver.ChooseTextureFormat(ctx, target,
1027                                                   GL_RGBA, GL_RGBA,
1028                                                   GL_UNSIGNED_BYTE);
1029 
1030       /* need a loop here just for cube maps */
1031       for (face = 0; face < numFaces; face++) {
1032          const GLenum faceTarget = _mesa_cube_face_target(target, face);
1033 
1034          /* initialize level[0] texture image */
1035          texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, 0);
1036 
1037          _mesa_init_teximage_fields(ctx, texImage,
1038                                     width,
1039                                     (dims > 1) ? height : 1,
1040                                     (dims > 2) ? depth : 1,
1041                                     0, /* border */
1042                                     GL_RGBA, texFormat);
1043 
1044          ctx->Driver.TexImage(ctx, dims, texImage,
1045                               GL_RGBA, GL_UNSIGNED_BYTE, texel,
1046                               &ctx->DefaultPacking);
1047       }
1048 
1049       _mesa_test_texobj_completeness(ctx, texObj);
1050       assert(texObj->_BaseComplete);
1051       assert(texObj->_MipmapComplete);
1052 
1053       ctx->Shared->FallbackTex[tex] = texObj;
1054 
1055       /* Complete the driver's operation in case another context will also
1056        * use the same fallback texture. */
1057       if (ctx->Driver.Finish)
1058          ctx->Driver.Finish(ctx);
1059    }
1060    return ctx->Shared->FallbackTex[tex];
1061 }
1062 
1063 
1064 /**
1065  * Compute the size of the given texture object, in bytes.
1066  */
1067 static GLuint
texture_size(const struct gl_texture_object * texObj)1068 texture_size(const struct gl_texture_object *texObj)
1069 {
1070    const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
1071    GLuint face, level, size = 0;
1072 
1073    for (face = 0; face < numFaces; face++) {
1074       for (level = 0; level < MAX_TEXTURE_LEVELS; level++) {
1075          const struct gl_texture_image *img = texObj->Image[face][level];
1076          if (img) {
1077             GLuint sz = _mesa_format_image_size(img->TexFormat, img->Width,
1078                                                 img->Height, img->Depth);
1079             size += sz;
1080          }
1081       }
1082    }
1083 
1084    return size;
1085 }
1086 
1087 
1088 /**
1089  * Callback called from _mesa_HashWalk()
1090  */
1091 static void
count_tex_size(GLuint key,void * data,void * userData)1092 count_tex_size(GLuint key, void *data, void *userData)
1093 {
1094    const struct gl_texture_object *texObj =
1095       (const struct gl_texture_object *) data;
1096    GLuint *total = (GLuint *) userData;
1097 
1098    (void) key;
1099 
1100    *total = *total + texture_size(texObj);
1101 }
1102 
1103 
1104 /**
1105  * Compute total size (in bytes) of all textures for the given context.
1106  * For debugging purposes.
1107  */
1108 GLuint
_mesa_total_texture_memory(struct gl_context * ctx)1109 _mesa_total_texture_memory(struct gl_context *ctx)
1110 {
1111    GLuint tgt, total = 0;
1112 
1113    _mesa_HashWalk(ctx->Shared->TexObjects, count_tex_size, &total);
1114 
1115    /* plus, the default texture objects */
1116    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
1117       total += texture_size(ctx->Shared->DefaultTex[tgt]);
1118    }
1119 
1120    return total;
1121 }
1122 
1123 
1124 /**
1125  * Return the base format for the given texture object by looking
1126  * at the base texture image.
1127  * \return base format (such as GL_RGBA) or GL_NONE if it can't be determined
1128  */
1129 GLenum
_mesa_texture_base_format(const struct gl_texture_object * texObj)1130 _mesa_texture_base_format(const struct gl_texture_object *texObj)
1131 {
1132    const struct gl_texture_image *texImage = _mesa_base_tex_image(texObj);
1133 
1134    return texImage ? texImage->_BaseFormat : GL_NONE;
1135 }
1136 
1137 
1138 static struct gl_texture_object *
invalidate_tex_image_error_check(struct gl_context * ctx,GLuint texture,GLint level,const char * name)1139 invalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture,
1140                                  GLint level, const char *name)
1141 {
1142    /* The GL_ARB_invalidate_subdata spec says:
1143     *
1144     *     "If <texture> is zero or is not the name of a texture, the error
1145     *     INVALID_VALUE is generated."
1146     *
1147     * This performs the error check in a different order than listed in the
1148     * spec.  We have to get the texture object before we can validate the
1149     * other parameters against values in the texture object.
1150     */
1151    struct gl_texture_object *const t = _mesa_lookup_texture(ctx, texture);
1152    if (texture == 0 || t == NULL) {
1153       _mesa_error(ctx, GL_INVALID_VALUE, "%s(texture)", name);
1154       return NULL;
1155    }
1156 
1157    /* The GL_ARB_invalidate_subdata spec says:
1158     *
1159     *     "If <level> is less than zero or greater than the base 2 logarithm
1160     *     of the maximum texture width, height, or depth, the error
1161     *     INVALID_VALUE is generated."
1162     */
1163    if (level < 0 || level > t->MaxLevel) {
1164       _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name);
1165       return NULL;
1166    }
1167 
1168    /* The GL_ARB_invalidate_subdata spec says:
1169     *
1170     *     "If the target of <texture> is TEXTURE_RECTANGLE, TEXTURE_BUFFER,
1171     *     TEXTURE_2D_MULTISAMPLE, or TEXTURE_2D_MULTISAMPLE_ARRAY, and <level>
1172     *     is not zero, the error INVALID_VALUE is generated."
1173     */
1174    if (level != 0) {
1175       switch (t->Target) {
1176       case GL_TEXTURE_RECTANGLE:
1177       case GL_TEXTURE_BUFFER:
1178       case GL_TEXTURE_2D_MULTISAMPLE:
1179       case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1180          _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name);
1181          return NULL;
1182 
1183       default:
1184          break;
1185       }
1186    }
1187 
1188    return t;
1189 }
1190 
1191 
1192 /**
1193  * Helper function for glCreateTextures and glGenTextures. Need this because
1194  * glCreateTextures should throw errors if target = 0. This is not exposed to
1195  * the rest of Mesa to encourage Mesa internals to use nameless textures,
1196  * which do not require expensive hash lookups.
1197  * \param target  either 0 or a valid / error-checked texture target enum
1198  */
1199 static void
create_textures(struct gl_context * ctx,GLenum target,GLsizei n,GLuint * textures,const char * caller)1200 create_textures(struct gl_context *ctx, GLenum target,
1201                 GLsizei n, GLuint *textures, const char *caller)
1202 {
1203    GLuint first;
1204    GLint i;
1205 
1206    if (!textures)
1207       return;
1208 
1209    /*
1210     * This must be atomic (generation and allocation of texture IDs)
1211     */
1212    _mesa_HashLockMutex(ctx->Shared->TexObjects);
1213 
1214    first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);
1215 
1216    /* Allocate new, empty texture objects */
1217    for (i = 0; i < n; i++) {
1218       struct gl_texture_object *texObj;
1219       GLuint name = first + i;
1220       texObj = ctx->Driver.NewTextureObject(ctx, name, target);
1221       if (!texObj) {
1222          _mesa_HashUnlockMutex(ctx->Shared->TexObjects);
1223          _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
1224          return;
1225       }
1226 
1227       /* insert into hash table */
1228       _mesa_HashInsertLocked(ctx->Shared->TexObjects, texObj->Name, texObj);
1229 
1230       textures[i] = name;
1231    }
1232 
1233    _mesa_HashUnlockMutex(ctx->Shared->TexObjects);
1234 }
1235 
1236 
1237 static void
create_textures_err(struct gl_context * ctx,GLenum target,GLsizei n,GLuint * textures,const char * caller)1238 create_textures_err(struct gl_context *ctx, GLenum target,
1239                     GLsizei n, GLuint *textures, const char *caller)
1240 {
1241    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1242       _mesa_debug(ctx, "%s %d\n", caller, n);
1243 
1244    if (n < 0) {
1245       _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", caller);
1246       return;
1247    }
1248 
1249    create_textures(ctx, target, n, textures, caller);
1250 }
1251 
1252 /*@}*/
1253 
1254 
1255 /***********************************************************************/
1256 /** \name API functions */
1257 /*@{*/
1258 
1259 
1260 /**
1261  * Generate texture names.
1262  *
1263  * \param n number of texture names to be generated.
1264  * \param textures an array in which will hold the generated texture names.
1265  *
1266  * \sa glGenTextures(), glCreateTextures().
1267  *
1268  * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture
1269  * IDs which are stored in \p textures.  Corresponding empty texture
1270  * objects are also generated.
1271  */
1272 void GLAPIENTRY
_mesa_GenTextures_no_error(GLsizei n,GLuint * textures)1273 _mesa_GenTextures_no_error(GLsizei n, GLuint *textures)
1274 {
1275    GET_CURRENT_CONTEXT(ctx);
1276    create_textures(ctx, 0, n, textures, "glGenTextures");
1277 }
1278 
1279 
1280 void GLAPIENTRY
_mesa_GenTextures(GLsizei n,GLuint * textures)1281 _mesa_GenTextures(GLsizei n, GLuint *textures)
1282 {
1283    GET_CURRENT_CONTEXT(ctx);
1284    create_textures_err(ctx, 0, n, textures, "glGenTextures");
1285 }
1286 
1287 /**
1288  * Create texture objects.
1289  *
1290  * \param target the texture target for each name to be generated.
1291  * \param n number of texture names to be generated.
1292  * \param textures an array in which will hold the generated texture names.
1293  *
1294  * \sa glCreateTextures(), glGenTextures().
1295  *
1296  * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture
1297  * IDs which are stored in \p textures.  Corresponding empty texture
1298  * objects are also generated.
1299  */
1300 void GLAPIENTRY
_mesa_CreateTextures_no_error(GLenum target,GLsizei n,GLuint * textures)1301 _mesa_CreateTextures_no_error(GLenum target, GLsizei n, GLuint *textures)
1302 {
1303    GET_CURRENT_CONTEXT(ctx);
1304    create_textures(ctx, target, n, textures, "glCreateTextures");
1305 }
1306 
1307 
1308 void GLAPIENTRY
_mesa_CreateTextures(GLenum target,GLsizei n,GLuint * textures)1309 _mesa_CreateTextures(GLenum target, GLsizei n, GLuint *textures)
1310 {
1311    GLint targetIndex;
1312    GET_CURRENT_CONTEXT(ctx);
1313 
1314    /*
1315     * The 4.5 core profile spec (30.10.2014) doesn't specify what
1316     * glCreateTextures should do with invalid targets, which was probably an
1317     * oversight.  This conforms to the spec for glBindTexture.
1318     */
1319    targetIndex = _mesa_tex_target_to_index(ctx, target);
1320    if (targetIndex < 0) {
1321       _mesa_error(ctx, GL_INVALID_ENUM, "glCreateTextures(target)");
1322       return;
1323    }
1324 
1325    create_textures_err(ctx, target, n, textures, "glCreateTextures");
1326 }
1327 
1328 /**
1329  * Check if the given texture object is bound to the current draw or
1330  * read framebuffer.  If so, Unbind it.
1331  */
1332 static void
unbind_texobj_from_fbo(struct gl_context * ctx,struct gl_texture_object * texObj)1333 unbind_texobj_from_fbo(struct gl_context *ctx,
1334                        struct gl_texture_object *texObj)
1335 {
1336    bool progress = false;
1337 
1338    /* Section 4.4.2 (Attaching Images to Framebuffer Objects), subsection
1339     * "Attaching Texture Images to a Framebuffer," of the OpenGL 3.1 spec
1340     * says:
1341     *
1342     *     "If a texture object is deleted while its image is attached to one
1343     *     or more attachment points in the currently bound framebuffer, then
1344     *     it is as if FramebufferTexture* had been called, with a texture of
1345     *     zero, for each attachment point to which this image was attached in
1346     *     the currently bound framebuffer. In other words, this texture image
1347     *     is first detached from all attachment points in the currently bound
1348     *     framebuffer. Note that the texture image is specifically not
1349     *     detached from any other framebuffer objects. Detaching the texture
1350     *     image from any other framebuffer objects is the responsibility of
1351     *     the application."
1352     */
1353    if (_mesa_is_user_fbo(ctx->DrawBuffer)) {
1354       progress = _mesa_detach_renderbuffer(ctx, ctx->DrawBuffer, texObj);
1355    }
1356    if (_mesa_is_user_fbo(ctx->ReadBuffer)
1357        && ctx->ReadBuffer != ctx->DrawBuffer) {
1358       progress = _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, texObj)
1359          || progress;
1360    }
1361 
1362    if (progress)
1363       /* Vertices are already flushed by _mesa_DeleteTextures */
1364       ctx->NewState |= _NEW_BUFFERS;
1365 }
1366 
1367 
1368 /**
1369  * Check if the given texture object is bound to any texture image units and
1370  * unbind it if so (revert to default textures).
1371  */
1372 static void
unbind_texobj_from_texunits(struct gl_context * ctx,struct gl_texture_object * texObj)1373 unbind_texobj_from_texunits(struct gl_context *ctx,
1374                             struct gl_texture_object *texObj)
1375 {
1376    const gl_texture_index index = texObj->TargetIndex;
1377    GLuint u;
1378 
1379    if (texObj->Target == 0) {
1380       /* texture was never bound */
1381       return;
1382    }
1383 
1384    assert(index < NUM_TEXTURE_TARGETS);
1385 
1386    for (u = 0; u < ctx->Texture.NumCurrentTexUsed; u++) {
1387       struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
1388 
1389       if (texObj == unit->CurrentTex[index]) {
1390          /* Bind the default texture for this unit/target */
1391          _mesa_reference_texobj(&unit->CurrentTex[index],
1392                                 ctx->Shared->DefaultTex[index]);
1393          unit->_BoundTextures &= ~(1 << index);
1394       }
1395    }
1396 }
1397 
1398 
1399 /**
1400  * Check if the given texture object is bound to any shader image unit
1401  * and unbind it if that's the case.
1402  */
1403 static void
unbind_texobj_from_image_units(struct gl_context * ctx,struct gl_texture_object * texObj)1404 unbind_texobj_from_image_units(struct gl_context *ctx,
1405                                struct gl_texture_object *texObj)
1406 {
1407    GLuint i;
1408 
1409    for (i = 0; i < ctx->Const.MaxImageUnits; i++) {
1410       struct gl_image_unit *unit = &ctx->ImageUnits[i];
1411 
1412       if (texObj == unit->TexObj) {
1413          _mesa_reference_texobj(&unit->TexObj, NULL);
1414          *unit = _mesa_default_image_unit(ctx);
1415       }
1416    }
1417 }
1418 
1419 
1420 /**
1421  * Unbinds all textures bound to the given texture image unit.
1422  */
1423 static void
unbind_textures_from_unit(struct gl_context * ctx,GLuint unit)1424 unbind_textures_from_unit(struct gl_context *ctx, GLuint unit)
1425 {
1426    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1427 
1428    while (texUnit->_BoundTextures) {
1429       const GLuint index = ffs(texUnit->_BoundTextures) - 1;
1430       struct gl_texture_object *texObj = ctx->Shared->DefaultTex[index];
1431 
1432       _mesa_reference_texobj(&texUnit->CurrentTex[index], texObj);
1433 
1434       /* Pass BindTexture call to device driver */
1435       if (ctx->Driver.BindTexture)
1436          ctx->Driver.BindTexture(ctx, unit, 0, texObj);
1437 
1438       texUnit->_BoundTextures &= ~(1 << index);
1439       ctx->NewState |= _NEW_TEXTURE_OBJECT;
1440    }
1441 }
1442 
1443 
1444 /**
1445  * Delete named textures.
1446  *
1447  * \param n number of textures to be deleted.
1448  * \param textures array of texture IDs to be deleted.
1449  *
1450  * \sa glDeleteTextures().
1451  *
1452  * If we're about to delete a texture that's currently bound to any
1453  * texture unit, unbind the texture first.  Decrement the reference
1454  * count on the texture object and delete it if it's zero.
1455  * Recall that texture objects can be shared among several rendering
1456  * contexts.
1457  */
1458 static void
delete_textures(struct gl_context * ctx,GLsizei n,const GLuint * textures)1459 delete_textures(struct gl_context *ctx, GLsizei n, const GLuint *textures)
1460 {
1461    FLUSH_VERTICES(ctx, 0); /* too complex */
1462 
1463    if (!textures)
1464       return;
1465 
1466    for (GLsizei i = 0; i < n; i++) {
1467       if (textures[i] > 0) {
1468          struct gl_texture_object *delObj
1469             = _mesa_lookup_texture(ctx, textures[i]);
1470 
1471          if (delObj) {
1472             _mesa_lock_texture(ctx, delObj);
1473 
1474             /* Check if texture is bound to any framebuffer objects.
1475              * If so, unbind.
1476              * See section 4.4.2.3 of GL_EXT_framebuffer_object.
1477              */
1478             unbind_texobj_from_fbo(ctx, delObj);
1479 
1480             /* Check if this texture is currently bound to any texture units.
1481              * If so, unbind it.
1482              */
1483             unbind_texobj_from_texunits(ctx, delObj);
1484 
1485             /* Check if this texture is currently bound to any shader
1486              * image unit.  If so, unbind it.
1487              * See section 3.9.X of GL_ARB_shader_image_load_store.
1488              */
1489             unbind_texobj_from_image_units(ctx, delObj);
1490 
1491             /* Make all handles that reference this texture object non-resident
1492              * in the current context.
1493              */
1494             _mesa_make_texture_handles_non_resident(ctx, delObj);
1495 
1496             _mesa_unlock_texture(ctx, delObj);
1497 
1498             ctx->NewState |= _NEW_TEXTURE_OBJECT;
1499 
1500             /* The texture _name_ is now free for re-use.
1501              * Remove it from the hash table now.
1502              */
1503             _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
1504 
1505             /* Unreference the texobj.  If refcount hits zero, the texture
1506              * will be deleted.
1507              */
1508             _mesa_reference_texobj(&delObj, NULL);
1509          }
1510       }
1511    }
1512 }
1513 
1514 /**
1515  * This deletes a texObj without altering the hash table.
1516  */
1517 void
_mesa_delete_nameless_texture(struct gl_context * ctx,struct gl_texture_object * texObj)1518 _mesa_delete_nameless_texture(struct gl_context *ctx,
1519                               struct gl_texture_object *texObj)
1520 {
1521    if (!texObj)
1522       return;
1523 
1524    FLUSH_VERTICES(ctx, 0);
1525 
1526    _mesa_lock_texture(ctx, texObj);
1527    {
1528       /* Check if texture is bound to any framebuffer objects.
1529        * If so, unbind.
1530        * See section 4.4.2.3 of GL_EXT_framebuffer_object.
1531        */
1532       unbind_texobj_from_fbo(ctx, texObj);
1533 
1534       /* Check if this texture is currently bound to any texture units.
1535        * If so, unbind it.
1536        */
1537       unbind_texobj_from_texunits(ctx, texObj);
1538 
1539       /* Check if this texture is currently bound to any shader
1540        * image unit.  If so, unbind it.
1541        * See section 3.9.X of GL_ARB_shader_image_load_store.
1542        */
1543       unbind_texobj_from_image_units(ctx, texObj);
1544    }
1545    _mesa_unlock_texture(ctx, texObj);
1546 
1547    ctx->NewState |= _NEW_TEXTURE_OBJECT;
1548 
1549    /* Unreference the texobj.  If refcount hits zero, the texture
1550     * will be deleted.
1551     */
1552    _mesa_reference_texobj(&texObj, NULL);
1553 }
1554 
1555 
1556 void GLAPIENTRY
_mesa_DeleteTextures_no_error(GLsizei n,const GLuint * textures)1557 _mesa_DeleteTextures_no_error(GLsizei n, const GLuint *textures)
1558 {
1559    GET_CURRENT_CONTEXT(ctx);
1560    delete_textures(ctx, n, textures);
1561 }
1562 
1563 
1564 void GLAPIENTRY
_mesa_DeleteTextures(GLsizei n,const GLuint * textures)1565 _mesa_DeleteTextures(GLsizei n, const GLuint *textures)
1566 {
1567    GET_CURRENT_CONTEXT(ctx);
1568 
1569    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1570       _mesa_debug(ctx, "glDeleteTextures %d\n", n);
1571 
1572    if (n < 0) {
1573       _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteTextures(n < 0)");
1574       return;
1575    }
1576 
1577    delete_textures(ctx, n, textures);
1578 }
1579 
1580 
1581 /**
1582  * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D
1583  * into the corresponding Mesa texture target index.
1584  * Note that proxy targets are not valid here.
1585  * \return TEXTURE_x_INDEX or -1 if target is invalid
1586  */
1587 int
_mesa_tex_target_to_index(const struct gl_context * ctx,GLenum target)1588 _mesa_tex_target_to_index(const struct gl_context *ctx, GLenum target)
1589 {
1590    switch (target) {
1591    case GL_TEXTURE_1D:
1592       return _mesa_is_desktop_gl(ctx) ? TEXTURE_1D_INDEX : -1;
1593    case GL_TEXTURE_2D:
1594       return TEXTURE_2D_INDEX;
1595    case GL_TEXTURE_3D:
1596       return ctx->API != API_OPENGLES ? TEXTURE_3D_INDEX : -1;
1597    case GL_TEXTURE_CUBE_MAP:
1598       return ctx->Extensions.ARB_texture_cube_map
1599          ? TEXTURE_CUBE_INDEX : -1;
1600    case GL_TEXTURE_RECTANGLE:
1601       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle
1602          ? TEXTURE_RECT_INDEX : -1;
1603    case GL_TEXTURE_1D_ARRAY:
1604       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array
1605          ? TEXTURE_1D_ARRAY_INDEX : -1;
1606    case GL_TEXTURE_2D_ARRAY:
1607       return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array)
1608          || _mesa_is_gles3(ctx)
1609          ? TEXTURE_2D_ARRAY_INDEX : -1;
1610    case GL_TEXTURE_BUFFER:
1611       return (_mesa_has_ARB_texture_buffer_object(ctx) ||
1612               _mesa_has_OES_texture_buffer(ctx)) ?
1613              TEXTURE_BUFFER_INDEX : -1;
1614    case GL_TEXTURE_EXTERNAL_OES:
1615       return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external
1616          ? TEXTURE_EXTERNAL_INDEX : -1;
1617    case GL_TEXTURE_CUBE_MAP_ARRAY:
1618       return _mesa_has_texture_cube_map_array(ctx)
1619          ? TEXTURE_CUBE_ARRAY_INDEX : -1;
1620    case GL_TEXTURE_2D_MULTISAMPLE:
1621       return ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample) ||
1622               _mesa_is_gles31(ctx)) ? TEXTURE_2D_MULTISAMPLE_INDEX: -1;
1623    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1624       return ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample) ||
1625               _mesa_is_gles31(ctx))
1626          ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: -1;
1627    default:
1628       return -1;
1629    }
1630 }
1631 
1632 
1633 /**
1634  * Do actual texture binding.  All error checking should have been done prior
1635  * to calling this function.  Note that the texture target (1D, 2D, etc) is
1636  * always specified by the texObj->TargetIndex.
1637  *
1638  * \param unit  index of texture unit to update
1639  * \param texObj  the new texture object (cannot be NULL)
1640  */
1641 static void
bind_texture_object(struct gl_context * ctx,unsigned unit,struct gl_texture_object * texObj)1642 bind_texture_object(struct gl_context *ctx, unsigned unit,
1643                     struct gl_texture_object *texObj)
1644 {
1645    struct gl_texture_unit *texUnit;
1646    int targetIndex;
1647 
1648    assert(unit < ARRAY_SIZE(ctx->Texture.Unit));
1649    texUnit = &ctx->Texture.Unit[unit];
1650 
1651    assert(texObj);
1652    assert(valid_texture_object(texObj));
1653 
1654    targetIndex = texObj->TargetIndex;
1655    assert(targetIndex >= 0);
1656    assert(targetIndex < NUM_TEXTURE_TARGETS);
1657 
1658    /* Check if this texture is only used by this context and is already bound.
1659     * If so, just return. For GL_OES_image_external, rebinding the texture
1660     * always must invalidate cached resources.
1661     */
1662    if (targetIndex != TEXTURE_EXTERNAL_INDEX) {
1663       bool early_out;
1664       simple_mtx_lock(&ctx->Shared->Mutex);
1665       early_out = ((ctx->Shared->RefCount == 1)
1666                    && (texObj == texUnit->CurrentTex[targetIndex]));
1667       simple_mtx_unlock(&ctx->Shared->Mutex);
1668       if (early_out) {
1669          return;
1670       }
1671    }
1672 
1673    /* flush before changing binding */
1674    FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT);
1675 
1676    /* If the refcount on the previously bound texture is decremented to
1677     * zero, it'll be deleted here.
1678     */
1679    _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], texObj);
1680 
1681    ctx->Texture.NumCurrentTexUsed = MAX2(ctx->Texture.NumCurrentTexUsed,
1682                                          unit + 1);
1683 
1684    if (texObj->Name != 0)
1685       texUnit->_BoundTextures |= (1 << targetIndex);
1686    else
1687       texUnit->_BoundTextures &= ~(1 << targetIndex);
1688 
1689    /* Pass BindTexture call to device driver */
1690    if (ctx->Driver.BindTexture) {
1691       ctx->Driver.BindTexture(ctx, unit, texObj->Target, texObj);
1692    }
1693 }
1694 
1695 /**
1696  * Light-weight bind texture for internal users
1697  *
1698  * This is really just \c finish_texture_init plus \c bind_texture_object.
1699  * This is intended to be used by internal Mesa functions that use
1700  * \c _mesa_CreateTexture and need to bind textures (e.g., meta).
1701  */
1702 void
_mesa_bind_texture(struct gl_context * ctx,GLenum target,struct gl_texture_object * tex_obj)1703 _mesa_bind_texture(struct gl_context *ctx, GLenum target,
1704                    struct gl_texture_object *tex_obj)
1705 {
1706    const GLint targetIndex = _mesa_tex_target_to_index(ctx, target);
1707 
1708    assert(targetIndex >= 0 && targetIndex < NUM_TEXTURE_TARGETS);
1709 
1710    if (tex_obj->Target == 0)
1711       finish_texture_init(ctx, target, tex_obj, targetIndex);
1712 
1713    assert(tex_obj->Target == target);
1714    assert(tex_obj->TargetIndex == targetIndex);
1715 
1716    bind_texture_object(ctx, ctx->Texture.CurrentUnit, tex_obj);
1717 }
1718 
1719 /**
1720  * Implement glBindTexture().  Do error checking, look-up or create a new
1721  * texture object, then bind it in the current texture unit.
1722  *
1723  * \param target texture target.
1724  * \param texName texture name.
1725  */
1726 static ALWAYS_INLINE void
bind_texture(struct gl_context * ctx,GLenum target,GLuint texName,bool no_error)1727 bind_texture(struct gl_context *ctx, GLenum target, GLuint texName,
1728              bool no_error)
1729 {
1730    struct gl_texture_object *newTexObj = NULL;
1731    int targetIndex;
1732 
1733    targetIndex = _mesa_tex_target_to_index(ctx, target);
1734    if (!no_error && targetIndex < 0) {
1735       _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target = %s)",
1736                   _mesa_enum_to_string(target));
1737       return;
1738    }
1739    assert(targetIndex < NUM_TEXTURE_TARGETS);
1740 
1741    /*
1742     * Get pointer to new texture object (newTexObj)
1743     */
1744    if (texName == 0) {
1745       /* Use a default texture object */
1746       newTexObj = ctx->Shared->DefaultTex[targetIndex];
1747    } else {
1748       /* non-default texture object */
1749       newTexObj = _mesa_lookup_texture(ctx, texName);
1750       if (newTexObj) {
1751          /* error checking */
1752          if (!no_error &&
1753              newTexObj->Target != 0 && newTexObj->Target != target) {
1754             /* The named texture object's target doesn't match the
1755              * given target
1756              */
1757             _mesa_error( ctx, GL_INVALID_OPERATION,
1758                          "glBindTexture(target mismatch)" );
1759             return;
1760          }
1761          if (newTexObj->Target == 0) {
1762             finish_texture_init(ctx, target, newTexObj, targetIndex);
1763          }
1764       }
1765       else {
1766          if (!no_error && ctx->API == API_OPENGL_CORE) {
1767             _mesa_error(ctx, GL_INVALID_OPERATION,
1768                         "glBindTexture(non-gen name)");
1769             return;
1770          }
1771 
1772          /* if this is a new texture id, allocate a texture object now */
1773          newTexObj = ctx->Driver.NewTextureObject(ctx, texName, target);
1774          if (!newTexObj) {
1775             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
1776             return;
1777          }
1778 
1779          /* and insert it into hash table */
1780          _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj);
1781       }
1782    }
1783 
1784    assert(newTexObj->Target == target);
1785    assert(newTexObj->TargetIndex == targetIndex);
1786 
1787    bind_texture_object(ctx, ctx->Texture.CurrentUnit, newTexObj);
1788 }
1789 
1790 void GLAPIENTRY
_mesa_BindTexture_no_error(GLenum target,GLuint texName)1791 _mesa_BindTexture_no_error(GLenum target, GLuint texName)
1792 {
1793    GET_CURRENT_CONTEXT(ctx);
1794    bind_texture(ctx, target, texName, true);
1795 }
1796 
1797 
1798 void GLAPIENTRY
_mesa_BindTexture(GLenum target,GLuint texName)1799 _mesa_BindTexture(GLenum target, GLuint texName)
1800 {
1801    GET_CURRENT_CONTEXT(ctx);
1802 
1803    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1804       _mesa_debug(ctx, "glBindTexture %s %d\n",
1805                   _mesa_enum_to_string(target), (GLint) texName);
1806 
1807    bind_texture(ctx, target, texName, false);
1808 }
1809 
1810 
1811 /**
1812  * OpenGL 4.5 / GL_ARB_direct_state_access glBindTextureUnit().
1813  *
1814  * \param unit texture unit.
1815  * \param texture texture name.
1816  *
1817  * \sa glBindTexture().
1818  *
1819  * If the named texture is 0, this will reset each target for the specified
1820  * texture unit to its default texture.
1821  * If the named texture is not 0 or a recognized texture name, this throws
1822  * GL_INVALID_OPERATION.
1823  */
1824 static ALWAYS_INLINE void
bind_texture_unit(struct gl_context * ctx,GLuint unit,GLuint texture,bool no_error)1825 bind_texture_unit(struct gl_context *ctx, GLuint unit, GLuint texture,
1826                   bool no_error)
1827 {
1828    struct gl_texture_object *texObj;
1829 
1830    /* Section 8.1 (Texture Objects) of the OpenGL 4.5 core profile spec
1831     * (20141030) says:
1832     *    "When texture is zero, each of the targets enumerated at the
1833     *    beginning of this section is reset to its default texture for the
1834     *    corresponding texture image unit."
1835     */
1836    if (texture == 0) {
1837       unbind_textures_from_unit(ctx, unit);
1838       return;
1839    }
1840 
1841    /* Get the non-default texture object */
1842    texObj = _mesa_lookup_texture(ctx, texture);
1843    if (!no_error) {
1844       /* Error checking */
1845       if (!texObj) {
1846          _mesa_error(ctx, GL_INVALID_OPERATION,
1847                      "glBindTextureUnit(non-gen name)");
1848          return;
1849       }
1850 
1851       if (texObj->Target == 0) {
1852          /* Texture object was gen'd but never bound so the target is not set */
1853          _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTextureUnit(target)");
1854          return;
1855       }
1856    }
1857 
1858    assert(valid_texture_object(texObj));
1859 
1860    bind_texture_object(ctx, unit, texObj);
1861 }
1862 
1863 
1864 void GLAPIENTRY
_mesa_BindTextureUnit_no_error(GLuint unit,GLuint texture)1865 _mesa_BindTextureUnit_no_error(GLuint unit, GLuint texture)
1866 {
1867    GET_CURRENT_CONTEXT(ctx);
1868    bind_texture_unit(ctx, unit, texture, true);
1869 }
1870 
1871 
1872 void GLAPIENTRY
_mesa_BindTextureUnit(GLuint unit,GLuint texture)1873 _mesa_BindTextureUnit(GLuint unit, GLuint texture)
1874 {
1875    GET_CURRENT_CONTEXT(ctx);
1876 
1877    if (unit >= _mesa_max_tex_unit(ctx)) {
1878       _mesa_error(ctx, GL_INVALID_VALUE, "glBindTextureUnit(unit=%u)", unit);
1879       return;
1880    }
1881 
1882    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1883       _mesa_debug(ctx, "glBindTextureUnit %s %d\n",
1884                   _mesa_enum_to_string(GL_TEXTURE0+unit), (GLint) texture);
1885 
1886    bind_texture_unit(ctx, unit, texture, false);
1887 }
1888 
1889 
1890 /**
1891  * OpenGL 4.4 / GL_ARB_multi_bind glBindTextures().
1892  */
1893 static ALWAYS_INLINE void
bind_textures(struct gl_context * ctx,GLuint first,GLsizei count,const GLuint * textures,bool no_error)1894 bind_textures(struct gl_context *ctx, GLuint first, GLsizei count,
1895               const GLuint *textures, bool no_error)
1896 {
1897    GLsizei i;
1898 
1899    if (textures) {
1900       /* Note that the error semantics for multi-bind commands differ from
1901        * those of other GL commands.
1902        *
1903        * The issues section in the ARB_multi_bind spec says:
1904        *
1905        *    "(11) Typically, OpenGL specifies that if an error is generated by
1906        *          a command, that command has no effect.  This is somewhat
1907        *          unfortunate for multi-bind commands, because it would require
1908        *          a first pass to scan the entire list of bound objects for
1909        *          errors and then a second pass to actually perform the
1910        *          bindings.  Should we have different error semantics?
1911        *
1912        *       RESOLVED:  Yes.  In this specification, when the parameters for
1913        *       one of the <count> binding points are invalid, that binding
1914        *       point is not updated and an error will be generated.  However,
1915        *       other binding points in the same command will be updated if
1916        *       their parameters are valid and no other error occurs."
1917        */
1918 
1919       _mesa_HashLockMutex(ctx->Shared->TexObjects);
1920 
1921       for (i = 0; i < count; i++) {
1922          if (textures[i] != 0) {
1923             struct gl_texture_unit *texUnit = &ctx->Texture.Unit[first + i];
1924             struct gl_texture_object *current = texUnit->_Current;
1925             struct gl_texture_object *texObj;
1926 
1927             if (current && current->Name == textures[i])
1928                texObj = current;
1929             else
1930                texObj = _mesa_lookup_texture_locked(ctx, textures[i]);
1931 
1932             if (texObj && texObj->Target != 0) {
1933                bind_texture_object(ctx, first + i, texObj);
1934             } else if (!no_error) {
1935                /* The ARB_multi_bind spec says:
1936                 *
1937                 *     "An INVALID_OPERATION error is generated if any value
1938                 *      in <textures> is not zero or the name of an existing
1939                 *      texture object (per binding)."
1940                 */
1941                _mesa_error(ctx, GL_INVALID_OPERATION,
1942                            "glBindTextures(textures[%d]=%u is not zero "
1943                            "or the name of an existing texture object)",
1944                            i, textures[i]);
1945             }
1946          } else {
1947             unbind_textures_from_unit(ctx, first + i);
1948          }
1949       }
1950 
1951       _mesa_HashUnlockMutex(ctx->Shared->TexObjects);
1952    } else {
1953       /* Unbind all textures in the range <first> through <first>+<count>-1 */
1954       for (i = 0; i < count; i++)
1955          unbind_textures_from_unit(ctx, first + i);
1956    }
1957 }
1958 
1959 
1960 void GLAPIENTRY
_mesa_BindTextures_no_error(GLuint first,GLsizei count,const GLuint * textures)1961 _mesa_BindTextures_no_error(GLuint first, GLsizei count, const GLuint *textures)
1962 {
1963    GET_CURRENT_CONTEXT(ctx);
1964    bind_textures(ctx, first, count, textures, true);
1965 }
1966 
1967 
1968 void GLAPIENTRY
_mesa_BindTextures(GLuint first,GLsizei count,const GLuint * textures)1969 _mesa_BindTextures(GLuint first, GLsizei count, const GLuint *textures)
1970 {
1971    GET_CURRENT_CONTEXT(ctx);
1972 
1973    /* The ARB_multi_bind spec says:
1974     *
1975     *     "An INVALID_OPERATION error is generated if <first> + <count>
1976     *      is greater than the number of texture image units supported
1977     *      by the implementation."
1978     */
1979    if (first + count > ctx->Const.MaxCombinedTextureImageUnits) {
1980       _mesa_error(ctx, GL_INVALID_OPERATION,
1981                   "glBindTextures(first=%u + count=%d > the value of "
1982                   "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS=%u)",
1983                   first, count, ctx->Const.MaxCombinedTextureImageUnits);
1984       return;
1985    }
1986 
1987    bind_textures(ctx, first, count, textures, false);
1988 }
1989 
1990 
1991 /**
1992  * Set texture priorities.
1993  *
1994  * \param n number of textures.
1995  * \param texName texture names.
1996  * \param priorities corresponding texture priorities.
1997  *
1998  * \sa glPrioritizeTextures().
1999  *
2000  * Looks up each texture in the hash, clamps the corresponding priority between
2001  * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture.
2002  */
2003 void GLAPIENTRY
_mesa_PrioritizeTextures(GLsizei n,const GLuint * texName,const GLclampf * priorities)2004 _mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,
2005                           const GLclampf *priorities )
2006 {
2007    GET_CURRENT_CONTEXT(ctx);
2008    GLint i;
2009 
2010    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2011       _mesa_debug(ctx, "glPrioritizeTextures %d\n", n);
2012 
2013    FLUSH_VERTICES(ctx, 0);
2014 
2015    if (n < 0) {
2016       _mesa_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" );
2017       return;
2018    }
2019 
2020    if (!priorities)
2021       return;
2022 
2023    for (i = 0; i < n; i++) {
2024       if (texName[i] > 0) {
2025          struct gl_texture_object *t = _mesa_lookup_texture(ctx, texName[i]);
2026          if (t) {
2027             t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );
2028          }
2029       }
2030    }
2031 
2032    ctx->NewState |= _NEW_TEXTURE_OBJECT;
2033 }
2034 
2035 
2036 
2037 /**
2038  * See if textures are loaded in texture memory.
2039  *
2040  * \param n number of textures to query.
2041  * \param texName array with the texture names.
2042  * \param residences array which will hold the residence status.
2043  *
2044  * \return GL_TRUE if all textures are resident and
2045  *                 residences is left unchanged,
2046  *
2047  * Note: we assume all textures are always resident
2048  */
2049 GLboolean GLAPIENTRY
_mesa_AreTexturesResident(GLsizei n,const GLuint * texName,GLboolean * residences)2050 _mesa_AreTexturesResident(GLsizei n, const GLuint *texName,
2051                           GLboolean *residences)
2052 {
2053    GET_CURRENT_CONTEXT(ctx);
2054    GLboolean allResident = GL_TRUE;
2055    GLint i;
2056    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
2057 
2058    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2059       _mesa_debug(ctx, "glAreTexturesResident %d\n", n);
2060 
2061    if (n < 0) {
2062       _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)");
2063       return GL_FALSE;
2064    }
2065 
2066    if (!texName || !residences)
2067       return GL_FALSE;
2068 
2069    /* We only do error checking on the texture names */
2070    for (i = 0; i < n; i++) {
2071       struct gl_texture_object *t;
2072       if (texName[i] == 0) {
2073          _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
2074          return GL_FALSE;
2075       }
2076       t = _mesa_lookup_texture(ctx, texName[i]);
2077       if (!t) {
2078          _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
2079          return GL_FALSE;
2080       }
2081    }
2082 
2083    return allResident;
2084 }
2085 
2086 
2087 /**
2088  * See if a name corresponds to a texture.
2089  *
2090  * \param texture texture name.
2091  *
2092  * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE
2093  * otherwise.
2094  *
2095  * \sa glIsTexture().
2096  *
2097  * Calls _mesa_HashLookup().
2098  */
2099 GLboolean GLAPIENTRY
_mesa_IsTexture(GLuint texture)2100 _mesa_IsTexture( GLuint texture )
2101 {
2102    struct gl_texture_object *t;
2103    GET_CURRENT_CONTEXT(ctx);
2104    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
2105 
2106    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2107       _mesa_debug(ctx, "glIsTexture %d\n", texture);
2108 
2109    if (!texture)
2110       return GL_FALSE;
2111 
2112    t = _mesa_lookup_texture(ctx, texture);
2113 
2114    /* IsTexture is true only after object has been bound once. */
2115    return t && t->Target;
2116 }
2117 
2118 
2119 /**
2120  * Simplest implementation of texture locking: grab the shared tex
2121  * mutex.  Examine the shared context state timestamp and if there has
2122  * been a change, set the appropriate bits in ctx->NewState.
2123  *
2124  * This is used to deal with synchronizing things when a texture object
2125  * is used/modified by different contexts (or threads) which are sharing
2126  * the texture.
2127  *
2128  * See also _mesa_lock/unlock_texture() in teximage.h
2129  */
2130 void
_mesa_lock_context_textures(struct gl_context * ctx)2131 _mesa_lock_context_textures( struct gl_context *ctx )
2132 {
2133    mtx_lock(&ctx->Shared->TexMutex);
2134 
2135    if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) {
2136       ctx->NewState |= _NEW_TEXTURE_OBJECT;
2137       ctx->TextureStateTimestamp = ctx->Shared->TextureStateStamp;
2138    }
2139 }
2140 
2141 
2142 void
_mesa_unlock_context_textures(struct gl_context * ctx)2143 _mesa_unlock_context_textures( struct gl_context *ctx )
2144 {
2145    assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp);
2146    mtx_unlock(&ctx->Shared->TexMutex);
2147 }
2148 
2149 
2150 void GLAPIENTRY
_mesa_InvalidateTexSubImage_no_error(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth)2151 _mesa_InvalidateTexSubImage_no_error(GLuint texture, GLint level, GLint xoffset,
2152                                      GLint yoffset, GLint zoffset,
2153                                      GLsizei width, GLsizei height,
2154                                      GLsizei depth)
2155 {
2156    /* no-op */
2157 }
2158 
2159 
2160 void GLAPIENTRY
_mesa_InvalidateTexSubImage(GLuint texture,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth)2161 _mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
2162                             GLint yoffset, GLint zoffset, GLsizei width,
2163                             GLsizei height, GLsizei depth)
2164 {
2165    struct gl_texture_object *t;
2166    struct gl_texture_image *image;
2167    GET_CURRENT_CONTEXT(ctx);
2168 
2169    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2170       _mesa_debug(ctx, "glInvalidateTexSubImage %d\n", texture);
2171 
2172    t = invalidate_tex_image_error_check(ctx, texture, level,
2173                                         "glInvalidateTexSubImage");
2174 
2175    /* The GL_ARB_invalidate_subdata spec says:
2176     *
2177     *     "...the specified subregion must be between -<b> and <dim>+<b> where
2178     *     <dim> is the size of the dimension of the texture image, and <b> is
2179     *     the size of the border of that texture image, otherwise
2180     *     INVALID_VALUE is generated (border is not applied to dimensions that
2181     *     don't exist in a given texture target)."
2182     */
2183    image = t->Image[0][level];
2184    if (image) {
2185       int xBorder;
2186       int yBorder;
2187       int zBorder;
2188       int imageWidth;
2189       int imageHeight;
2190       int imageDepth;
2191 
2192       /* The GL_ARB_invalidate_subdata spec says:
2193        *
2194        *     "For texture targets that don't have certain dimensions, this
2195        *     command treats those dimensions as having a size of 1. For
2196        *     example, to invalidate a portion of a two-dimensional texture,
2197        *     the application would use <zoffset> equal to zero and <depth>
2198        *     equal to one."
2199        */
2200       switch (t->Target) {
2201       case GL_TEXTURE_BUFFER:
2202          xBorder = 0;
2203          yBorder = 0;
2204          zBorder = 0;
2205          imageWidth = 1;
2206          imageHeight = 1;
2207          imageDepth = 1;
2208          break;
2209       case GL_TEXTURE_1D:
2210          xBorder = image->Border;
2211          yBorder = 0;
2212          zBorder = 0;
2213          imageWidth = image->Width;
2214          imageHeight = 1;
2215          imageDepth = 1;
2216          break;
2217       case GL_TEXTURE_1D_ARRAY:
2218          xBorder = image->Border;
2219          yBorder = 0;
2220          zBorder = 0;
2221          imageWidth = image->Width;
2222          imageHeight = image->Height;
2223          imageDepth = 1;
2224          break;
2225       case GL_TEXTURE_2D:
2226       case GL_TEXTURE_CUBE_MAP:
2227       case GL_TEXTURE_RECTANGLE:
2228       case GL_TEXTURE_2D_MULTISAMPLE:
2229          xBorder = image->Border;
2230          yBorder = image->Border;
2231          zBorder = 0;
2232          imageWidth = image->Width;
2233          imageHeight = image->Height;
2234          imageDepth = 1;
2235          break;
2236       case GL_TEXTURE_2D_ARRAY:
2237       case GL_TEXTURE_CUBE_MAP_ARRAY:
2238       case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2239          xBorder = image->Border;
2240          yBorder = image->Border;
2241          zBorder = 0;
2242          imageWidth = image->Width;
2243          imageHeight = image->Height;
2244          imageDepth = image->Depth;
2245          break;
2246       case GL_TEXTURE_3D:
2247          xBorder = image->Border;
2248          yBorder = image->Border;
2249          zBorder = image->Border;
2250          imageWidth = image->Width;
2251          imageHeight = image->Height;
2252          imageDepth = image->Depth;
2253          break;
2254       default:
2255          assert(!"Should not get here.");
2256          xBorder = 0;
2257          yBorder = 0;
2258          zBorder = 0;
2259          imageWidth = 0;
2260          imageHeight = 0;
2261          imageDepth = 0;
2262          break;
2263       }
2264 
2265       if (xoffset < -xBorder) {
2266          _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(xoffset)");
2267          return;
2268       }
2269 
2270       if (xoffset + width > imageWidth + xBorder) {
2271          _mesa_error(ctx, GL_INVALID_VALUE,
2272                      "glInvalidateSubTexImage(xoffset+width)");
2273          return;
2274       }
2275 
2276       if (yoffset < -yBorder) {
2277          _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(yoffset)");
2278          return;
2279       }
2280 
2281       if (yoffset + height > imageHeight + yBorder) {
2282          _mesa_error(ctx, GL_INVALID_VALUE,
2283                      "glInvalidateSubTexImage(yoffset+height)");
2284          return;
2285       }
2286 
2287       if (zoffset < -zBorder) {
2288          _mesa_error(ctx, GL_INVALID_VALUE,
2289                      "glInvalidateSubTexImage(zoffset)");
2290          return;
2291       }
2292 
2293       if (zoffset + depth  > imageDepth + zBorder) {
2294          _mesa_error(ctx, GL_INVALID_VALUE,
2295                      "glInvalidateSubTexImage(zoffset+depth)");
2296          return;
2297       }
2298    }
2299 
2300    /* We don't actually do anything for this yet.  Just return after
2301     * validating the parameters and generating the required errors.
2302     */
2303    return;
2304 }
2305 
2306 
2307 void GLAPIENTRY
_mesa_InvalidateTexImage_no_error(GLuint texture,GLint level)2308 _mesa_InvalidateTexImage_no_error(GLuint texture, GLint level)
2309 {
2310    /* no-op */
2311 }
2312 
2313 
2314 void GLAPIENTRY
_mesa_InvalidateTexImage(GLuint texture,GLint level)2315 _mesa_InvalidateTexImage(GLuint texture, GLint level)
2316 {
2317    GET_CURRENT_CONTEXT(ctx);
2318 
2319    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2320       _mesa_debug(ctx, "glInvalidateTexImage(%d, %d)\n", texture, level);
2321 
2322    invalidate_tex_image_error_check(ctx, texture, level,
2323                                     "glInvalidateTexImage");
2324 
2325    /* We don't actually do anything for this yet.  Just return after
2326     * validating the parameters and generating the required errors.
2327     */
2328    return;
2329 }
2330 
2331 /*@}*/
2332