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