3 * Texture object management.
7 * Mesa 3-D graphics library
9 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
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:
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
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.
31 #include "bufferobj.h"
44 #include "program/prog_instruction.h"
48 /**********************************************************************/
49 /** \name Internal functions */
54 * Return the gl_texture_object for a given ID.
56 struct gl_texture_object
*
57 _mesa_lookup_texture(struct gl_context
*ctx
, GLuint id
)
59 return (struct gl_texture_object
*)
60 _mesa_HashLookup(ctx
->Shared
->TexObjects
, id
);
65 _mesa_begin_texture_lookups(struct gl_context
*ctx
)
67 _mesa_HashLockMutex(ctx
->Shared
->TexObjects
);
72 _mesa_end_texture_lookups(struct gl_context
*ctx
)
74 _mesa_HashUnlockMutex(ctx
->Shared
->TexObjects
);
78 struct gl_texture_object
*
79 _mesa_lookup_texture_locked(struct gl_context
*ctx
, GLuint id
)
81 return (struct gl_texture_object
*)
82 _mesa_HashLookupLocked(ctx
->Shared
->TexObjects
, id
);
87 * Allocate and initialize a new texture object. But don't put it into the
88 * texture object hash table.
90 * Called via ctx->Driver.NewTextureObject, unless overridden by a device
93 * \param shared the shared GL state structure to contain the texture object
94 * \param name integer name for the texture object
95 * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
96 * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV. zero is ok for the sake
99 * \return pointer to new texture object.
101 struct gl_texture_object
*
102 _mesa_new_texture_object( struct gl_context
*ctx
, GLuint name
, GLenum target
)
104 struct gl_texture_object
*obj
;
106 obj
= MALLOC_STRUCT(gl_texture_object
);
107 _mesa_initialize_texture_object(ctx
, obj
, name
, target
);
113 * Initialize a new texture object to default values.
114 * \param obj the texture object
115 * \param name the texture name
116 * \param target the texture target
119 _mesa_initialize_texture_object( struct gl_context
*ctx
,
120 struct gl_texture_object
*obj
,
121 GLuint name
, GLenum target
)
123 ASSERT(target
== 0 ||
124 target
== GL_TEXTURE_1D
||
125 target
== GL_TEXTURE_2D
||
126 target
== GL_TEXTURE_3D
||
127 target
== GL_TEXTURE_CUBE_MAP_ARB
||
128 target
== GL_TEXTURE_RECTANGLE_NV
||
129 target
== GL_TEXTURE_1D_ARRAY_EXT
||
130 target
== GL_TEXTURE_2D_ARRAY_EXT
||
131 target
== GL_TEXTURE_EXTERNAL_OES
||
132 target
== GL_TEXTURE_CUBE_MAP_ARRAY
||
133 target
== GL_TEXTURE_BUFFER
||
134 target
== GL_TEXTURE_2D_MULTISAMPLE
||
135 target
== GL_TEXTURE_2D_MULTISAMPLE_ARRAY
);
137 memset(obj
, 0, sizeof(*obj
));
138 /* init the non-zero fields */
139 mtx_init(&obj
->Mutex
, mtx_plain
);
142 obj
->Target
= target
;
143 obj
->Priority
= 1.0F
;
145 obj
->MaxLevel
= 1000;
147 /* must be one; no support for (YUV) planes in separate buffers */
148 obj
->RequiredTextureImageUnits
= 1;
151 if (target
== GL_TEXTURE_RECTANGLE_NV
||
152 target
== GL_TEXTURE_EXTERNAL_OES
) {
153 obj
->Sampler
.WrapS
= GL_CLAMP_TO_EDGE
;
154 obj
->Sampler
.WrapT
= GL_CLAMP_TO_EDGE
;
155 obj
->Sampler
.WrapR
= GL_CLAMP_TO_EDGE
;
156 obj
->Sampler
.MinFilter
= GL_LINEAR
;
159 obj
->Sampler
.WrapS
= GL_REPEAT
;
160 obj
->Sampler
.WrapT
= GL_REPEAT
;
161 obj
->Sampler
.WrapR
= GL_REPEAT
;
162 obj
->Sampler
.MinFilter
= GL_NEAREST_MIPMAP_LINEAR
;
164 obj
->Sampler
.MagFilter
= GL_LINEAR
;
165 obj
->Sampler
.MinLod
= -1000.0;
166 obj
->Sampler
.MaxLod
= 1000.0;
167 obj
->Sampler
.LodBias
= 0.0;
168 obj
->Sampler
.MaxAnisotropy
= 1.0;
169 obj
->Sampler
.CompareMode
= GL_NONE
; /* ARB_shadow */
170 obj
->Sampler
.CompareFunc
= GL_LEQUAL
; /* ARB_shadow */
171 obj
->DepthMode
= ctx
->API
== API_OPENGL_CORE
? GL_RED
: GL_LUMINANCE
;
172 obj
->StencilSampling
= false;
173 obj
->Sampler
.CubeMapSeamless
= GL_FALSE
;
174 obj
->Swizzle
[0] = GL_RED
;
175 obj
->Swizzle
[1] = GL_GREEN
;
176 obj
->Swizzle
[2] = GL_BLUE
;
177 obj
->Swizzle
[3] = GL_ALPHA
;
178 obj
->_Swizzle
= SWIZZLE_NOOP
;
179 obj
->Sampler
.sRGBDecode
= GL_DECODE_EXT
;
180 obj
->BufferObjectFormat
= GL_R8
;
181 obj
->_BufferObjectFormat
= MESA_FORMAT_R_UNORM8
;
182 obj
->ImageFormatCompatibilityType
= GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE
;
187 * Some texture initialization can't be finished until we know which
188 * target it's getting bound to (GL_TEXTURE_1D/2D/etc).
191 finish_texture_init(struct gl_context
*ctx
, GLenum target
,
192 struct gl_texture_object
*obj
)
194 GLenum filter
= GL_LINEAR
;
195 assert(obj
->Target
== 0);
198 case GL_TEXTURE_2D_MULTISAMPLE
:
199 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY
:
203 case GL_TEXTURE_RECTANGLE_NV
:
204 case GL_TEXTURE_EXTERNAL_OES
:
205 /* have to init wrap and filter state here - kind of klunky */
206 obj
->Sampler
.WrapS
= GL_CLAMP_TO_EDGE
;
207 obj
->Sampler
.WrapT
= GL_CLAMP_TO_EDGE
;
208 obj
->Sampler
.WrapR
= GL_CLAMP_TO_EDGE
;
209 obj
->Sampler
.MinFilter
= filter
;
210 obj
->Sampler
.MagFilter
= filter
;
211 if (ctx
->Driver
.TexParameter
) {
212 static const GLfloat fparam_wrap
[1] = {(GLfloat
) GL_CLAMP_TO_EDGE
};
213 const GLfloat fparam_filter
[1] = {(GLfloat
) filter
};
214 ctx
->Driver
.TexParameter(ctx
, obj
, GL_TEXTURE_WRAP_S
, fparam_wrap
);
215 ctx
->Driver
.TexParameter(ctx
, obj
, GL_TEXTURE_WRAP_T
, fparam_wrap
);
216 ctx
->Driver
.TexParameter(ctx
, obj
, GL_TEXTURE_WRAP_R
, fparam_wrap
);
217 ctx
->Driver
.TexParameter(ctx
, obj
,
218 GL_TEXTURE_MIN_FILTER
, fparam_filter
);
219 ctx
->Driver
.TexParameter(ctx
, obj
,
220 GL_TEXTURE_MAG_FILTER
, fparam_filter
);
225 /* nothing needs done */
232 * Deallocate a texture object struct. It should have already been
233 * removed from the texture object pool.
234 * Called via ctx->Driver.DeleteTexture() if not overriden by a driver.
236 * \param shared the shared GL state to which the object belongs.
237 * \param texObj the texture object to delete.
240 _mesa_delete_texture_object(struct gl_context
*ctx
,
241 struct gl_texture_object
*texObj
)
245 /* Set Target to an invalid value. With some assertions elsewhere
246 * we can try to detect possible use of deleted textures.
248 texObj
->Target
= 0x99;
250 /* free the texture images */
251 for (face
= 0; face
< 6; face
++) {
252 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++) {
253 if (texObj
->Image
[face
][i
]) {
254 ctx
->Driver
.DeleteTextureImage(ctx
, texObj
->Image
[face
][i
]);
259 _mesa_reference_buffer_object(ctx
, &texObj
->BufferObject
, NULL
);
261 /* destroy the mutex -- it may have allocated memory (eg on bsd) */
262 mtx_destroy(&texObj
->Mutex
);
266 /* free this object */
273 * Copy texture object state from one texture object to another.
274 * Use for glPush/PopAttrib.
276 * \param dest destination texture object.
277 * \param src source texture object.
280 _mesa_copy_texture_object( struct gl_texture_object
*dest
,
281 const struct gl_texture_object
*src
)
283 dest
->Target
= src
->Target
;
284 dest
->TargetIndex
= src
->TargetIndex
;
285 dest
->Name
= src
->Name
;
286 dest
->Priority
= src
->Priority
;
287 dest
->Sampler
.BorderColor
.f
[0] = src
->Sampler
.BorderColor
.f
[0];
288 dest
->Sampler
.BorderColor
.f
[1] = src
->Sampler
.BorderColor
.f
[1];
289 dest
->Sampler
.BorderColor
.f
[2] = src
->Sampler
.BorderColor
.f
[2];
290 dest
->Sampler
.BorderColor
.f
[3] = src
->Sampler
.BorderColor
.f
[3];
291 dest
->Sampler
.WrapS
= src
->Sampler
.WrapS
;
292 dest
->Sampler
.WrapT
= src
->Sampler
.WrapT
;
293 dest
->Sampler
.WrapR
= src
->Sampler
.WrapR
;
294 dest
->Sampler
.MinFilter
= src
->Sampler
.MinFilter
;
295 dest
->Sampler
.MagFilter
= src
->Sampler
.MagFilter
;
296 dest
->Sampler
.MinLod
= src
->Sampler
.MinLod
;
297 dest
->Sampler
.MaxLod
= src
->Sampler
.MaxLod
;
298 dest
->Sampler
.LodBias
= src
->Sampler
.LodBias
;
299 dest
->BaseLevel
= src
->BaseLevel
;
300 dest
->MaxLevel
= src
->MaxLevel
;
301 dest
->Sampler
.MaxAnisotropy
= src
->Sampler
.MaxAnisotropy
;
302 dest
->Sampler
.CompareMode
= src
->Sampler
.CompareMode
;
303 dest
->Sampler
.CompareFunc
= src
->Sampler
.CompareFunc
;
304 dest
->Sampler
.CubeMapSeamless
= src
->Sampler
.CubeMapSeamless
;
305 dest
->DepthMode
= src
->DepthMode
;
306 dest
->StencilSampling
= src
->StencilSampling
;
307 dest
->Sampler
.sRGBDecode
= src
->Sampler
.sRGBDecode
;
308 dest
->_MaxLevel
= src
->_MaxLevel
;
309 dest
->_MaxLambda
= src
->_MaxLambda
;
310 dest
->GenerateMipmap
= src
->GenerateMipmap
;
311 dest
->_BaseComplete
= src
->_BaseComplete
;
312 dest
->_MipmapComplete
= src
->_MipmapComplete
;
313 COPY_4V(dest
->Swizzle
, src
->Swizzle
);
314 dest
->_Swizzle
= src
->_Swizzle
;
316 dest
->RequiredTextureImageUnits
= src
->RequiredTextureImageUnits
;
321 * Free all texture images of the given texture object.
323 * \param ctx GL context.
324 * \param t texture object.
326 * \sa _mesa_clear_texture_image().
329 _mesa_clear_texture_object(struct gl_context
*ctx
,
330 struct gl_texture_object
*texObj
)
334 if (texObj
->Target
== 0)
337 for (i
= 0; i
< MAX_FACES
; i
++) {
338 for (j
= 0; j
< MAX_TEXTURE_LEVELS
; j
++) {
339 struct gl_texture_image
*texImage
= texObj
->Image
[i
][j
];
341 _mesa_clear_texture_image(ctx
, texImage
);
348 * Check if the given texture object is valid by examining its Target field.
349 * For debugging only.
352 valid_texture_object(const struct gl_texture_object
*tex
)
354 switch (tex
->Target
) {
359 case GL_TEXTURE_CUBE_MAP_ARB
:
360 case GL_TEXTURE_RECTANGLE_NV
:
361 case GL_TEXTURE_1D_ARRAY_EXT
:
362 case GL_TEXTURE_2D_ARRAY_EXT
:
363 case GL_TEXTURE_BUFFER
:
364 case GL_TEXTURE_EXTERNAL_OES
:
365 case GL_TEXTURE_CUBE_MAP_ARRAY
:
366 case GL_TEXTURE_2D_MULTISAMPLE
:
367 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY
:
370 _mesa_problem(NULL
, "invalid reference to a deleted texture object");
373 _mesa_problem(NULL
, "invalid texture object Target 0x%x, Id = %u",
374 tex
->Target
, tex
->Name
);
381 * Reference (or unreference) a texture object.
382 * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero).
383 * If 'tex' is non-null, increment its refcount.
384 * This is normally only called from the _mesa_reference_texobj() macro
385 * when there's a real pointer change.
388 _mesa_reference_texobj_(struct gl_texture_object
**ptr
,
389 struct gl_texture_object
*tex
)
394 /* Unreference the old texture */
395 GLboolean deleteFlag
= GL_FALSE
;
396 struct gl_texture_object
*oldTex
= *ptr
;
398 ASSERT(valid_texture_object(oldTex
));
399 (void) valid_texture_object
; /* silence warning in release builds */
401 mtx_lock(&oldTex
->Mutex
);
402 ASSERT(oldTex
->RefCount
> 0);
405 deleteFlag
= (oldTex
->RefCount
== 0);
406 mtx_unlock(&oldTex
->Mutex
);
409 GET_CURRENT_CONTEXT(ctx
);
411 ctx
->Driver
.DeleteTexture(ctx
, oldTex
);
413 _mesa_problem(NULL
, "Unable to delete texture, no context");
421 /* reference new texture */
422 ASSERT(valid_texture_object(tex
));
423 mtx_lock(&tex
->Mutex
);
424 if (tex
->RefCount
== 0) {
425 /* this texture's being deleted (look just above) */
426 /* Not sure this can every really happen. Warn if it does. */
427 _mesa_problem(NULL
, "referencing deleted texture object");
434 mtx_unlock(&tex
->Mutex
);
439 enum base_mipmap
{ BASE
, MIPMAP
};
443 * Mark a texture object as incomplete. There are actually three kinds of
445 * 1. "base incomplete": the base level of the texture is invalid so no
446 * texturing is possible.
447 * 2. "mipmap incomplete": a non-base level of the texture is invalid so
448 * mipmap filtering isn't possible, but non-mipmap filtering is.
449 * 3. "texture incompleteness": some combination of texture state and
450 * sampler state renders the texture incomplete.
452 * \param t texture object
453 * \param bm either BASE or MIPMAP to indicate what's incomplete
454 * \param fmt... string describing why it's incomplete (for debugging).
457 incomplete(struct gl_texture_object
*t
, enum base_mipmap bm
,
458 const char *fmt
, ...)
460 if (MESA_DEBUG_FLAGS
& DEBUG_INCOMPLETE_TEXTURE
) {
465 vsnprintf(s
, sizeof(s
), fmt
, args
);
468 _mesa_debug(NULL
, "Texture Obj %d incomplete because: %s\n", t
->Name
, s
);
472 t
->_BaseComplete
= GL_FALSE
;
473 t
->_MipmapComplete
= GL_FALSE
;
478 * Examine a texture object to determine if it is complete.
480 * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE
483 * \param ctx GL context.
484 * \param t texture object.
486 * According to the texture target, verifies that each of the mipmaps is
487 * present and has the expected size.
490 _mesa_test_texobj_completeness( const struct gl_context
*ctx
,
491 struct gl_texture_object
*t
)
493 const GLint baseLevel
= t
->BaseLevel
;
494 const struct gl_texture_image
*baseImage
;
497 /* We'll set these to FALSE if tests fail below */
498 t
->_BaseComplete
= GL_TRUE
;
499 t
->_MipmapComplete
= GL_TRUE
;
501 if (t
->Target
== GL_TEXTURE_BUFFER
) {
502 /* Buffer textures are always considered complete. The obvious case where
503 * they would be incomplete (no BO attached) is actually specced to be
504 * undefined rendering results.
509 /* Detect cases where the application set the base level to an invalid
512 if ((baseLevel
< 0) || (baseLevel
>= MAX_TEXTURE_LEVELS
)) {
513 incomplete(t
, BASE
, "base level = %d is invalid", baseLevel
);
517 if (t
->MaxLevel
< baseLevel
) {
518 incomplete(t
, MIPMAP
, "MAX_LEVEL (%d) < BASE_LEVEL (%d)",
519 t
->MaxLevel
, baseLevel
);
523 baseImage
= t
->Image
[0][baseLevel
];
525 /* Always need the base level image */
527 incomplete(t
, BASE
, "Image[baseLevel=%d] == NULL", baseLevel
);
531 /* Check width/height/depth for zero */
532 if (baseImage
->Width
== 0 ||
533 baseImage
->Height
== 0 ||
534 baseImage
->Depth
== 0) {
535 incomplete(t
, BASE
, "texture width or height or depth = 0");
539 /* Check if the texture values are integer */
541 GLenum datatype
= _mesa_get_format_datatype(baseImage
->TexFormat
);
542 t
->_IsIntegerFormat
= datatype
== GL_INT
|| datatype
== GL_UNSIGNED_INT
;
545 /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the
546 * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state).
550 case GL_TEXTURE_1D_ARRAY_EXT
:
551 maxLevels
= ctx
->Const
.MaxTextureLevels
;
554 case GL_TEXTURE_2D_ARRAY_EXT
:
555 maxLevels
= ctx
->Const
.MaxTextureLevels
;
558 maxLevels
= ctx
->Const
.Max3DTextureLevels
;
560 case GL_TEXTURE_CUBE_MAP_ARB
:
561 case GL_TEXTURE_CUBE_MAP_ARRAY
:
562 maxLevels
= ctx
->Const
.MaxCubeTextureLevels
;
564 case GL_TEXTURE_RECTANGLE_NV
:
565 case GL_TEXTURE_BUFFER
:
566 case GL_TEXTURE_EXTERNAL_OES
:
567 case GL_TEXTURE_2D_MULTISAMPLE
:
568 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY
:
569 maxLevels
= 1; /* no mipmapping */
572 _mesa_problem(ctx
, "Bad t->Target in _mesa_test_texobj_completeness");
576 ASSERT(maxLevels
> 0);
578 t
->_MaxLevel
= MIN3(t
->MaxLevel
,
579 /* 'p' in the GL spec */
580 (int) (baseLevel
+ baseImage
->MaxNumLevels
- 1),
581 /* 'q' in the GL spec */
585 /* Adjust max level for views: the data store may have more levels than
588 t
->_MaxLevel
= MIN2(t
->_MaxLevel
, t
->NumLevels
- 1);
591 /* Compute _MaxLambda = q - p in the spec used during mipmapping */
592 t
->_MaxLambda
= (GLfloat
) (t
->_MaxLevel
- baseLevel
);
595 /* This texture object was created with glTexStorage1/2/3D() so we
596 * know that all the mipmap levels are the right size and all cube
597 * map faces are the same size.
598 * We don't need to do any of the additional checks below.
603 if (t
->Target
== GL_TEXTURE_CUBE_MAP_ARB
) {
604 /* Make sure that all six cube map level 0 images are the same size.
605 * Note: we know that the image's width==height (we enforce that
606 * at glTexImage time) so we only need to test the width here.
609 assert(baseImage
->Width2
== baseImage
->Height
);
610 for (face
= 1; face
< 6; face
++) {
611 assert(t
->Image
[face
][baseLevel
] == NULL
||
612 t
->Image
[face
][baseLevel
]->Width2
==
613 t
->Image
[face
][baseLevel
]->Height2
);
614 if (t
->Image
[face
][baseLevel
] == NULL
||
615 t
->Image
[face
][baseLevel
]->Width2
!= baseImage
->Width2
) {
616 incomplete(t
, BASE
, "Cube face missing or mismatched size");
623 * Do mipmap consistency checking.
624 * Note: we don't care about the current texture sampler state here.
625 * To determine texture completeness we'll either look at _BaseComplete
626 * or _MipmapComplete depending on the current minification filter mode.
630 const GLint minLevel
= baseLevel
;
631 const GLint maxLevel
= t
->_MaxLevel
;
632 const GLuint numFaces
= _mesa_num_tex_faces(t
->Target
);
633 GLuint width
, height
, depth
, face
;
635 if (minLevel
> maxLevel
) {
636 incomplete(t
, MIPMAP
, "minLevel > maxLevel");
640 /* Get the base image's dimensions */
641 width
= baseImage
->Width2
;
642 height
= baseImage
->Height2
;
643 depth
= baseImage
->Depth2
;
645 /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL,
646 * MULTISAMPLE and MULTISAMPLE_ARRAY textures
648 for (i
= baseLevel
+ 1; i
< maxLevels
; i
++) {
649 /* Compute the expected size of image at level[i] */
653 if (height
> 1 && t
->Target
!= GL_TEXTURE_1D_ARRAY
) {
656 if (depth
> 1 && t
->Target
!= GL_TEXTURE_2D_ARRAY
&& t
->Target
!= GL_TEXTURE_CUBE_MAP_ARRAY
) {
660 /* loop over cube faces (or single face otherwise) */
661 for (face
= 0; face
< numFaces
; face
++) {
662 if (i
>= minLevel
&& i
<= maxLevel
) {
663 const struct gl_texture_image
*img
= t
->Image
[face
][i
];
666 incomplete(t
, MIPMAP
, "TexImage[%d] is missing", i
);
669 if (img
->TexFormat
!= baseImage
->TexFormat
) {
670 incomplete(t
, MIPMAP
, "Format[i] != Format[baseLevel]");
673 if (img
->Border
!= baseImage
->Border
) {
674 incomplete(t
, MIPMAP
, "Border[i] != Border[baseLevel]");
677 if (img
->Width2
!= width
) {
678 incomplete(t
, MIPMAP
, "TexImage[%d] bad width %u", i
, img
->Width2
);
681 if (img
->Height2
!= height
) {
682 incomplete(t
, MIPMAP
, "TexImage[%d] bad height %u", i
, img
->Height2
);
685 if (img
->Depth2
!= depth
) {
686 incomplete(t
, MIPMAP
, "TexImage[%d] bad depth %u", i
, img
->Depth2
);
690 /* Extra checks for cube textures */
692 /* check that cube faces are the same size */
693 if (img
->Width2
!= t
->Image
[0][i
]->Width2
||
694 img
->Height2
!= t
->Image
[0][i
]->Height2
) {
695 incomplete(t
, MIPMAP
, "CubeMap Image[n][i] bad size");
702 if (width
== 1 && height
== 1 && depth
== 1) {
703 return; /* found smallest needed mipmap, all done! */
711 * Check if the given cube map texture is "cube complete" as defined in
712 * the OpenGL specification.
715 _mesa_cube_complete(const struct gl_texture_object
*texObj
)
717 const GLint baseLevel
= texObj
->BaseLevel
;
718 const struct gl_texture_image
*img0
, *img
;
721 if (texObj
->Target
!= GL_TEXTURE_CUBE_MAP
)
724 if ((baseLevel
< 0) || (baseLevel
>= MAX_TEXTURE_LEVELS
))
727 /* check first face */
728 img0
= texObj
->Image
[0][baseLevel
];
731 img0
->Width
!= img0
->Height
)
734 /* check remaining faces vs. first face */
735 for (face
= 1; face
< 6; face
++) {
736 img
= texObj
->Image
[face
][baseLevel
];
738 img
->Width
!= img0
->Width
||
739 img
->Height
!= img0
->Height
||
740 img
->TexFormat
!= img0
->TexFormat
)
749 * Mark a texture object dirty. It forces the object to be incomplete
750 * and forces the context to re-validate its state.
752 * \param ctx GL context.
753 * \param texObj texture object.
756 _mesa_dirty_texobj(struct gl_context
*ctx
, struct gl_texture_object
*texObj
)
758 texObj
->_BaseComplete
= GL_FALSE
;
759 texObj
->_MipmapComplete
= GL_FALSE
;
760 ctx
->NewState
|= _NEW_TEXTURE
;
765 * Return pointer to a default/fallback texture of the given type/target.
766 * The texture is an RGBA texture with all texels = (0,0,0,1).
767 * That's the value a GLSL sampler should get when sampling from an
768 * incomplete texture.
770 struct gl_texture_object
*
771 _mesa_get_fallback_texture(struct gl_context
*ctx
, gl_texture_index tex
)
773 if (!ctx
->Shared
->FallbackTex
[tex
]) {
774 /* create fallback texture now */
775 const GLsizei width
= 1, height
= 1, depth
= 1;
777 struct gl_texture_object
*texObj
;
778 struct gl_texture_image
*texImage
;
779 mesa_format texFormat
;
780 GLuint dims
, face
, numFaces
= 1;
789 case TEXTURE_2D_ARRAY_INDEX
:
791 target
= GL_TEXTURE_2D_ARRAY
;
793 case TEXTURE_1D_ARRAY_INDEX
:
795 target
= GL_TEXTURE_1D_ARRAY
;
797 case TEXTURE_CUBE_INDEX
:
799 target
= GL_TEXTURE_CUBE_MAP
;
802 case TEXTURE_3D_INDEX
:
804 target
= GL_TEXTURE_3D
;
806 case TEXTURE_RECT_INDEX
:
808 target
= GL_TEXTURE_RECTANGLE
;
810 case TEXTURE_2D_INDEX
:
812 target
= GL_TEXTURE_2D
;
814 case TEXTURE_1D_INDEX
:
816 target
= GL_TEXTURE_1D
;
818 case TEXTURE_BUFFER_INDEX
:
820 target
= GL_TEXTURE_BUFFER
;
822 case TEXTURE_CUBE_ARRAY_INDEX
:
824 target
= GL_TEXTURE_CUBE_MAP_ARRAY
;
826 case TEXTURE_EXTERNAL_INDEX
:
828 target
= GL_TEXTURE_EXTERNAL_OES
;
830 case TEXTURE_2D_MULTISAMPLE_INDEX
:
832 target
= GL_TEXTURE_2D_MULTISAMPLE
;
834 case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX
:
836 target
= GL_TEXTURE_2D_MULTISAMPLE_ARRAY
;
843 /* create texture object */
844 texObj
= ctx
->Driver
.NewTextureObject(ctx
, 0, target
);
848 assert(texObj
->RefCount
== 1);
849 texObj
->Sampler
.MinFilter
= GL_NEAREST
;
850 texObj
->Sampler
.MagFilter
= GL_NEAREST
;
852 texFormat
= ctx
->Driver
.ChooseTextureFormat(ctx
, target
,
856 /* need a loop here just for cube maps */
857 for (face
= 0; face
< numFaces
; face
++) {
860 if (target
== GL_TEXTURE_CUBE_MAP
)
861 faceTarget
= GL_TEXTURE_CUBE_MAP_POSITIVE_X
+ face
;
865 /* initialize level[0] texture image */
866 texImage
= _mesa_get_tex_image(ctx
, texObj
, faceTarget
, 0);
868 _mesa_init_teximage_fields(ctx
, texImage
,
870 (dims
> 1) ? height
: 1,
871 (dims
> 2) ? depth
: 1,
875 ctx
->Driver
.TexImage(ctx
, dims
, texImage
,
876 GL_RGBA
, GL_UNSIGNED_BYTE
, texel
,
877 &ctx
->DefaultPacking
);
880 _mesa_test_texobj_completeness(ctx
, texObj
);
881 assert(texObj
->_BaseComplete
);
882 assert(texObj
->_MipmapComplete
);
884 ctx
->Shared
->FallbackTex
[tex
] = texObj
;
886 return ctx
->Shared
->FallbackTex
[tex
];
891 * Compute the size of the given texture object, in bytes.
894 texture_size(const struct gl_texture_object
*texObj
)
896 const GLuint numFaces
= _mesa_num_tex_faces(texObj
->Target
);
897 GLuint face
, level
, size
= 0;
899 for (face
= 0; face
< numFaces
; face
++) {
900 for (level
= 0; level
< MAX_TEXTURE_LEVELS
; level
++) {
901 const struct gl_texture_image
*img
= texObj
->Image
[face
][level
];
903 GLuint sz
= _mesa_format_image_size(img
->TexFormat
, img
->Width
,
904 img
->Height
, img
->Depth
);
915 * Callback called from _mesa_HashWalk()
918 count_tex_size(GLuint key
, void *data
, void *userData
)
920 const struct gl_texture_object
*texObj
=
921 (const struct gl_texture_object
*) data
;
922 GLuint
*total
= (GLuint
*) userData
;
926 *total
= *total
+ texture_size(texObj
);
931 * Compute total size (in bytes) of all textures for the given context.
932 * For debugging purposes.
935 _mesa_total_texture_memory(struct gl_context
*ctx
)
937 GLuint tgt
, total
= 0;
939 _mesa_HashWalk(ctx
->Shared
->TexObjects
, count_tex_size
, &total
);
941 /* plus, the default texture objects */
942 for (tgt
= 0; tgt
< NUM_TEXTURE_TARGETS
; tgt
++) {
943 total
+= texture_size(ctx
->Shared
->DefaultTex
[tgt
]);
949 static struct gl_texture_object
*
950 invalidate_tex_image_error_check(struct gl_context
*ctx
, GLuint texture
,
951 GLint level
, const char *name
)
953 /* The GL_ARB_invalidate_subdata spec says:
955 * "If <texture> is zero or is not the name of a texture, the error
956 * INVALID_VALUE is generated."
958 * This performs the error check in a different order than listed in the
959 * spec. We have to get the texture object before we can validate the
960 * other parameters against values in the texture object.
962 struct gl_texture_object
*const t
= _mesa_lookup_texture(ctx
, texture
);
963 if (texture
== 0 || t
== NULL
) {
964 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(texture)", name
);
968 /* The GL_ARB_invalidate_subdata spec says:
970 * "If <level> is less than zero or greater than the base 2 logarithm
971 * of the maximum texture width, height, or depth, the error
972 * INVALID_VALUE is generated."
974 if (level
< 0 || level
> t
->MaxLevel
) {
975 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(level)", name
);
979 /* The GL_ARB_invalidate_subdata spec says:
981 * "If the target of <texture> is TEXTURE_RECTANGLE, TEXTURE_BUFFER,
982 * TEXTURE_2D_MULTISAMPLE, or TEXTURE_2D_MULTISAMPLE_ARRAY, and <level>
983 * is not zero, the error INVALID_VALUE is generated."
987 case GL_TEXTURE_RECTANGLE
:
988 case GL_TEXTURE_BUFFER
:
989 case GL_TEXTURE_2D_MULTISAMPLE
:
990 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY
:
991 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(level)", name
);
1005 /***********************************************************************/
1006 /** \name API functions */
1011 * Generate texture names.
1013 * \param n number of texture names to be generated.
1014 * \param textures an array in which will hold the generated texture names.
1016 * \sa glGenTextures().
1018 * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture
1019 * IDs which are stored in \p textures. Corresponding empty texture
1020 * objects are also generated.
1023 _mesa_GenTextures( GLsizei n
, GLuint
*textures
)
1025 GET_CURRENT_CONTEXT(ctx
);
1029 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
1030 _mesa_debug(ctx
, "glGenTextures %d\n", n
);
1033 _mesa_error( ctx
, GL_INVALID_VALUE
, "glGenTextures" );
1041 * This must be atomic (generation and allocation of texture IDs)
1043 mtx_lock(&ctx
->Shared
->Mutex
);
1045 first
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->TexObjects
, n
);
1047 /* Allocate new, empty texture objects */
1048 for (i
= 0; i
< n
; i
++) {
1049 struct gl_texture_object
*texObj
;
1050 GLuint name
= first
+ i
;
1052 texObj
= ctx
->Driver
.NewTextureObject(ctx
, name
, target
);
1054 mtx_unlock(&ctx
->Shared
->Mutex
);
1055 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glGenTextures");
1059 /* insert into hash table */
1060 _mesa_HashInsert(ctx
->Shared
->TexObjects
, texObj
->Name
, texObj
);
1065 mtx_unlock(&ctx
->Shared
->Mutex
);
1070 * Check if the given texture object is bound to the current draw or
1071 * read framebuffer. If so, Unbind it.
1074 unbind_texobj_from_fbo(struct gl_context
*ctx
,
1075 struct gl_texture_object
*texObj
)
1077 bool progress
= false;
1079 /* Section 4.4.2 (Attaching Images to Framebuffer Objects), subsection
1080 * "Attaching Texture Images to a Framebuffer," of the OpenGL 3.1 spec
1083 * "If a texture object is deleted while its image is attached to one
1084 * or more attachment points in the currently bound framebuffer, then
1085 * it is as if FramebufferTexture* had been called, with a texture of
1086 * zero, for each attachment point to which this image was attached in
1087 * the currently bound framebuffer. In other words, this texture image
1088 * is first detached from all attachment points in the currently bound
1089 * framebuffer. Note that the texture image is specifically not
1090 * detached from any other framebuffer objects. Detaching the texture
1091 * image from any other framebuffer objects is the responsibility of
1094 if (_mesa_is_user_fbo(ctx
->DrawBuffer
)) {
1095 progress
= _mesa_detach_renderbuffer(ctx
, ctx
->DrawBuffer
, texObj
);
1097 if (_mesa_is_user_fbo(ctx
->ReadBuffer
)
1098 && ctx
->ReadBuffer
!= ctx
->DrawBuffer
) {
1099 progress
= _mesa_detach_renderbuffer(ctx
, ctx
->ReadBuffer
, texObj
)
1104 /* Vertices are already flushed by _mesa_DeleteTextures */
1105 ctx
->NewState
|= _NEW_BUFFERS
;
1110 * Check if the given texture object is bound to any texture image units and
1111 * unbind it if so (revert to default textures).
1114 unbind_texobj_from_texunits(struct gl_context
*ctx
,
1115 struct gl_texture_object
*texObj
)
1117 const gl_texture_index index
= texObj
->TargetIndex
;
1120 if (texObj
->Target
== 0)
1123 for (u
= 0; u
< ctx
->Texture
.NumCurrentTexUsed
; u
++) {
1124 struct gl_texture_unit
*unit
= &ctx
->Texture
.Unit
[u
];
1126 if (texObj
== unit
->CurrentTex
[index
]) {
1127 /* Bind the default texture for this unit/target */
1128 _mesa_reference_texobj(&unit
->CurrentTex
[index
],
1129 ctx
->Shared
->DefaultTex
[index
]);
1130 unit
->_BoundTextures
&= ~(1 << index
);
1137 * Check if the given texture object is bound to any shader image unit
1138 * and unbind it if that's the case.
1141 unbind_texobj_from_image_units(struct gl_context
*ctx
,
1142 struct gl_texture_object
*texObj
)
1146 for (i
= 0; i
< ctx
->Const
.MaxImageUnits
; i
++) {
1147 struct gl_image_unit
*unit
= &ctx
->ImageUnits
[i
];
1149 if (texObj
== unit
->TexObj
)
1150 _mesa_reference_texobj(&unit
->TexObj
, NULL
);
1155 * Unbinds all textures bound to the given texture image unit.
1158 unbind_textures_from_unit(struct gl_context
*ctx
, GLuint unit
)
1160 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
1162 while (texUnit
->_BoundTextures
) {
1163 const GLuint index
= ffs(texUnit
->_BoundTextures
) - 1;
1164 struct gl_texture_object
*texObj
= ctx
->Shared
->DefaultTex
[index
];
1166 _mesa_reference_texobj(&texUnit
->CurrentTex
[index
], texObj
);
1168 /* Pass BindTexture call to device driver */
1169 if (ctx
->Driver
.BindTexture
)
1170 ctx
->Driver
.BindTexture(ctx
, unit
, 0, texObj
);
1172 texUnit
->_BoundTextures
&= ~(1 << index
);
1173 ctx
->NewState
|= _NEW_TEXTURE
;
1178 * Delete named textures.
1180 * \param n number of textures to be deleted.
1181 * \param textures array of texture IDs to be deleted.
1183 * \sa glDeleteTextures().
1185 * If we're about to delete a texture that's currently bound to any
1186 * texture unit, unbind the texture first. Decrement the reference
1187 * count on the texture object and delete it if it's zero.
1188 * Recall that texture objects can be shared among several rendering
1192 _mesa_DeleteTextures( GLsizei n
, const GLuint
*textures
)
1194 GET_CURRENT_CONTEXT(ctx
);
1197 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
1198 _mesa_debug(ctx
, "glDeleteTextures %d\n", n
);
1200 FLUSH_VERTICES(ctx
, 0); /* too complex */
1205 for (i
= 0; i
< n
; i
++) {
1206 if (textures
[i
] > 0) {
1207 struct gl_texture_object
*delObj
1208 = _mesa_lookup_texture(ctx
, textures
[i
]);
1211 _mesa_lock_texture(ctx
, delObj
);
1213 /* Check if texture is bound to any framebuffer objects.
1215 * See section 4.4.2.3 of GL_EXT_framebuffer_object.
1217 unbind_texobj_from_fbo(ctx
, delObj
);
1219 /* Check if this texture is currently bound to any texture units.
1222 unbind_texobj_from_texunits(ctx
, delObj
);
1224 /* Check if this texture is currently bound to any shader
1225 * image unit. If so, unbind it.
1226 * See section 3.9.X of GL_ARB_shader_image_load_store.
1228 unbind_texobj_from_image_units(ctx
, delObj
);
1230 _mesa_unlock_texture(ctx
, delObj
);
1232 ctx
->NewState
|= _NEW_TEXTURE
;
1234 /* The texture _name_ is now free for re-use.
1235 * Remove it from the hash table now.
1237 mtx_lock(&ctx
->Shared
->Mutex
);
1238 _mesa_HashRemove(ctx
->Shared
->TexObjects
, delObj
->Name
);
1239 mtx_unlock(&ctx
->Shared
->Mutex
);
1241 /* Unreference the texobj. If refcount hits zero, the texture
1244 _mesa_reference_texobj(&delObj
, NULL
);
1252 * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D
1253 * into the corresponding Mesa texture target index.
1254 * Note that proxy targets are not valid here.
1255 * \return TEXTURE_x_INDEX or -1 if target is invalid
1258 _mesa_tex_target_to_index(const struct gl_context
*ctx
, GLenum target
)
1262 return _mesa_is_desktop_gl(ctx
) ? TEXTURE_1D_INDEX
: -1;
1264 return TEXTURE_2D_INDEX
;
1266 return ctx
->API
!= API_OPENGLES
? TEXTURE_3D_INDEX
: -1;
1267 case GL_TEXTURE_CUBE_MAP
:
1268 return ctx
->Extensions
.ARB_texture_cube_map
1269 ? TEXTURE_CUBE_INDEX
: -1;
1270 case GL_TEXTURE_RECTANGLE
:
1271 return _mesa_is_desktop_gl(ctx
) && ctx
->Extensions
.NV_texture_rectangle
1272 ? TEXTURE_RECT_INDEX
: -1;
1273 case GL_TEXTURE_1D_ARRAY
:
1274 return _mesa_is_desktop_gl(ctx
) && ctx
->Extensions
.EXT_texture_array
1275 ? TEXTURE_1D_ARRAY_INDEX
: -1;
1276 case GL_TEXTURE_2D_ARRAY
:
1277 return (_mesa_is_desktop_gl(ctx
) && ctx
->Extensions
.EXT_texture_array
)
1278 || _mesa_is_gles3(ctx
)
1279 ? TEXTURE_2D_ARRAY_INDEX
: -1;
1280 case GL_TEXTURE_BUFFER
:
1281 return ctx
->API
== API_OPENGL_CORE
&&
1282 ctx
->Extensions
.ARB_texture_buffer_object
?
1283 TEXTURE_BUFFER_INDEX
: -1;
1284 case GL_TEXTURE_EXTERNAL_OES
:
1285 return _mesa_is_gles(ctx
) && ctx
->Extensions
.OES_EGL_image_external
1286 ? TEXTURE_EXTERNAL_INDEX
: -1;
1287 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1288 return _mesa_is_desktop_gl(ctx
) && ctx
->Extensions
.ARB_texture_cube_map_array
1289 ? TEXTURE_CUBE_ARRAY_INDEX
: -1;
1290 case GL_TEXTURE_2D_MULTISAMPLE
:
1291 return _mesa_is_desktop_gl(ctx
) && ctx
->Extensions
.ARB_texture_multisample
1292 ? TEXTURE_2D_MULTISAMPLE_INDEX
: -1;
1293 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY
:
1294 return _mesa_is_desktop_gl(ctx
) && ctx
->Extensions
.ARB_texture_multisample
1295 ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX
: -1;
1303 * Bind a named texture to a texturing target.
1305 * \param target texture target.
1306 * \param texName texture name.
1308 * \sa glBindTexture().
1310 * Determines the old texture object bound and returns immediately if rebinding
1311 * the same texture. Get the current texture which is either a default texture
1312 * if name is null, a named texture from the hash, or a new texture if the
1313 * given texture name is new. Increments its reference count, binds it, and
1314 * calls dd_function_table::BindTexture. Decrements the old texture reference
1315 * count and deletes it if it reaches zero.
1318 _mesa_BindTexture( GLenum target
, GLuint texName
)
1320 GET_CURRENT_CONTEXT(ctx
);
1321 struct gl_texture_unit
*texUnit
= _mesa_get_current_tex_unit(ctx
);
1322 struct gl_texture_object
*newTexObj
= NULL
;
1325 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
1326 _mesa_debug(ctx
, "glBindTexture %s %d\n",
1327 _mesa_lookup_enum_by_nr(target
), (GLint
) texName
);
1329 targetIndex
= _mesa_tex_target_to_index(ctx
, target
);
1330 if (targetIndex
< 0) {
1331 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBindTexture(target)");
1334 assert(targetIndex
< NUM_TEXTURE_TARGETS
);
1337 * Get pointer to new texture object (newTexObj)
1340 /* Use a default texture object */
1341 newTexObj
= ctx
->Shared
->DefaultTex
[targetIndex
];
1344 /* non-default texture object */
1345 newTexObj
= _mesa_lookup_texture(ctx
, texName
);
1347 /* error checking */
1348 if (newTexObj
->Target
!= 0 && newTexObj
->Target
!= target
) {
1349 /* the named texture object's target doesn't match the given target */
1350 _mesa_error( ctx
, GL_INVALID_OPERATION
,
1351 "glBindTexture(target mismatch)" );
1354 if (newTexObj
->Target
== 0) {
1355 finish_texture_init(ctx
, target
, newTexObj
);
1359 if (ctx
->API
== API_OPENGL_CORE
) {
1360 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glBindTexture(non-gen name)");
1364 /* if this is a new texture id, allocate a texture object now */
1365 newTexObj
= ctx
->Driver
.NewTextureObject(ctx
, texName
, target
);
1367 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindTexture");
1371 /* and insert it into hash table */
1372 mtx_lock(&ctx
->Shared
->Mutex
);
1373 _mesa_HashInsert(ctx
->Shared
->TexObjects
, texName
, newTexObj
);
1374 mtx_unlock(&ctx
->Shared
->Mutex
);
1376 newTexObj
->Target
= target
;
1377 newTexObj
->TargetIndex
= targetIndex
;
1380 assert(valid_texture_object(newTexObj
));
1382 /* Check if this texture is only used by this context and is already bound.
1383 * If so, just return.
1386 GLboolean early_out
;
1387 mtx_lock(&ctx
->Shared
->Mutex
);
1388 early_out
= ((ctx
->Shared
->RefCount
== 1)
1389 && (newTexObj
== texUnit
->CurrentTex
[targetIndex
]));
1390 mtx_unlock(&ctx
->Shared
->Mutex
);
1396 /* flush before changing binding */
1397 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
1399 /* Do the actual binding. The refcount on the previously bound
1400 * texture object will be decremented. It'll be deleted if the
1403 _mesa_reference_texobj(&texUnit
->CurrentTex
[targetIndex
], newTexObj
);
1404 ctx
->Texture
.NumCurrentTexUsed
= MAX2(ctx
->Texture
.NumCurrentTexUsed
,
1405 ctx
->Texture
.CurrentUnit
+ 1);
1406 ASSERT(texUnit
->CurrentTex
[targetIndex
]);
1409 texUnit
->_BoundTextures
|= (1 << targetIndex
);
1411 texUnit
->_BoundTextures
&= ~(1 << targetIndex
);
1413 /* Pass BindTexture call to device driver */
1414 if (ctx
->Driver
.BindTexture
)
1415 ctx
->Driver
.BindTexture(ctx
, ctx
->Texture
.CurrentUnit
, target
, newTexObj
);
1420 _mesa_BindTextures(GLuint first
, GLsizei count
, const GLuint
*textures
)
1422 GET_CURRENT_CONTEXT(ctx
);
1425 /* The ARB_multi_bind spec says:
1427 * "An INVALID_OPERATION error is generated if <first> + <count>
1428 * is greater than the number of texture image units supported
1429 * by the implementation."
1431 if (first
+ count
> ctx
->Const
.MaxCombinedTextureImageUnits
) {
1432 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1433 "glBindTextures(first=%u + count=%d > the value of "
1434 "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS=%u)",
1435 first
, count
, ctx
->Const
.MaxCombinedTextureImageUnits
);
1439 /* Flush before changing bindings */
1440 FLUSH_VERTICES(ctx
, 0);
1442 ctx
->Texture
.NumCurrentTexUsed
= MAX2(ctx
->Texture
.NumCurrentTexUsed
,
1446 /* Note that the error semantics for multi-bind commands differ from
1447 * those of other GL commands.
1449 * The issues section in the ARB_multi_bind spec says:
1451 * "(11) Typically, OpenGL specifies that if an error is generated by
1452 * a command, that command has no effect. This is somewhat
1453 * unfortunate for multi-bind commands, because it would require
1454 * a first pass to scan the entire list of bound objects for
1455 * errors and then a second pass to actually perform the
1456 * bindings. Should we have different error semantics?
1458 * RESOLVED: Yes. In this specification, when the parameters for
1459 * one of the <count> binding points are invalid, that binding
1460 * point is not updated and an error will be generated. However,
1461 * other binding points in the same command will be updated if
1462 * their parameters are valid and no other error occurs."
1465 _mesa_begin_texture_lookups(ctx
);
1467 for (i
= 0; i
< count
; i
++) {
1468 if (textures
[i
] != 0) {
1469 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[first
+ i
];
1470 struct gl_texture_object
*current
= texUnit
->_Current
;
1471 struct gl_texture_object
*texObj
;
1473 if (current
&& current
->Name
== textures
[i
])
1476 texObj
= _mesa_lookup_texture_locked(ctx
, textures
[i
]);
1478 if (texObj
&& texObj
->Target
!= 0) {
1479 const gl_texture_index targetIndex
= texObj
->TargetIndex
;
1481 if (texUnit
->CurrentTex
[targetIndex
] != texObj
) {
1482 /* Do the actual binding. The refcount on the previously
1483 * bound texture object will be decremented. It will be
1484 * deleted if the count hits zero.
1486 _mesa_reference_texobj(&texUnit
->CurrentTex
[targetIndex
],
1489 texUnit
->_BoundTextures
|= (1 << targetIndex
);
1490 ctx
->NewState
|= _NEW_TEXTURE
;
1492 /* Pass the BindTexture call to the device driver */
1493 if (ctx
->Driver
.BindTexture
)
1494 ctx
->Driver
.BindTexture(ctx
, first
+ i
,
1495 texObj
->Target
, texObj
);
1498 /* The ARB_multi_bind spec says:
1500 * "An INVALID_OPERATION error is generated if any value
1501 * in <textures> is not zero or the name of an existing
1502 * texture object (per binding)."
1504 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1505 "glBindTextures(textures[%d]=%u is not zero "
1506 "or the name of an existing texture object)",
1510 unbind_textures_from_unit(ctx
, first
+ i
);
1514 _mesa_end_texture_lookups(ctx
);
1516 /* Unbind all textures in the range <first> through <first>+<count>-1 */
1517 for (i
= 0; i
< count
; i
++)
1518 unbind_textures_from_unit(ctx
, first
+ i
);
1524 * Set texture priorities.
1526 * \param n number of textures.
1527 * \param texName texture names.
1528 * \param priorities corresponding texture priorities.
1530 * \sa glPrioritizeTextures().
1532 * Looks up each texture in the hash, clamps the corresponding priority between
1533 * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture.
1536 _mesa_PrioritizeTextures( GLsizei n
, const GLuint
*texName
,
1537 const GLclampf
*priorities
)
1539 GET_CURRENT_CONTEXT(ctx
);
1542 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
1543 _mesa_debug(ctx
, "glPrioritizeTextures %d\n", n
);
1545 FLUSH_VERTICES(ctx
, 0);
1548 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPrioritizeTextures" );
1555 for (i
= 0; i
< n
; i
++) {
1556 if (texName
[i
] > 0) {
1557 struct gl_texture_object
*t
= _mesa_lookup_texture(ctx
, texName
[i
]);
1559 t
->Priority
= CLAMP( priorities
[i
], 0.0F
, 1.0F
);
1564 ctx
->NewState
|= _NEW_TEXTURE
;
1570 * See if textures are loaded in texture memory.
1572 * \param n number of textures to query.
1573 * \param texName array with the texture names.
1574 * \param residences array which will hold the residence status.
1576 * \return GL_TRUE if all textures are resident and \p residences is left unchanged,
1578 * Note: we assume all textures are always resident
1580 GLboolean GLAPIENTRY
1581 _mesa_AreTexturesResident(GLsizei n
, const GLuint
*texName
,
1582 GLboolean
*residences
)
1584 GET_CURRENT_CONTEXT(ctx
);
1585 GLboolean allResident
= GL_TRUE
;
1587 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx
, GL_FALSE
);
1589 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
1590 _mesa_debug(ctx
, "glAreTexturesResident %d\n", n
);
1593 _mesa_error(ctx
, GL_INVALID_VALUE
, "glAreTexturesResident(n)");
1597 if (!texName
|| !residences
)
1600 /* We only do error checking on the texture names */
1601 for (i
= 0; i
< n
; i
++) {
1602 struct gl_texture_object
*t
;
1603 if (texName
[i
] == 0) {
1604 _mesa_error(ctx
, GL_INVALID_VALUE
, "glAreTexturesResident");
1607 t
= _mesa_lookup_texture(ctx
, texName
[i
]);
1609 _mesa_error(ctx
, GL_INVALID_VALUE
, "glAreTexturesResident");
1619 * See if a name corresponds to a texture.
1621 * \param texture texture name.
1623 * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE
1626 * \sa glIsTexture().
1628 * Calls _mesa_HashLookup().
1630 GLboolean GLAPIENTRY
1631 _mesa_IsTexture( GLuint texture
)
1633 struct gl_texture_object
*t
;
1634 GET_CURRENT_CONTEXT(ctx
);
1635 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx
, GL_FALSE
);
1637 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
1638 _mesa_debug(ctx
, "glIsTexture %d\n", texture
);
1643 t
= _mesa_lookup_texture(ctx
, texture
);
1645 /* IsTexture is true only after object has been bound once. */
1646 return t
&& t
->Target
;
1651 * Simplest implementation of texture locking: grab the shared tex
1652 * mutex. Examine the shared context state timestamp and if there has
1653 * been a change, set the appropriate bits in ctx->NewState.
1655 * This is used to deal with synchronizing things when a texture object
1656 * is used/modified by different contexts (or threads) which are sharing
1659 * See also _mesa_lock/unlock_texture() in teximage.h
1662 _mesa_lock_context_textures( struct gl_context
*ctx
)
1664 mtx_lock(&ctx
->Shared
->TexMutex
);
1666 if (ctx
->Shared
->TextureStateStamp
!= ctx
->TextureStateTimestamp
) {
1667 ctx
->NewState
|= _NEW_TEXTURE
;
1668 ctx
->TextureStateTimestamp
= ctx
->Shared
->TextureStateStamp
;
1674 _mesa_unlock_context_textures( struct gl_context
*ctx
)
1676 assert(ctx
->Shared
->TextureStateStamp
== ctx
->TextureStateTimestamp
);
1677 mtx_unlock(&ctx
->Shared
->TexMutex
);
1681 _mesa_InvalidateTexSubImage(GLuint texture
, GLint level
, GLint xoffset
,
1682 GLint yoffset
, GLint zoffset
, GLsizei width
,
1683 GLsizei height
, GLsizei depth
)
1685 struct gl_texture_object
*t
;
1686 struct gl_texture_image
*image
;
1687 GET_CURRENT_CONTEXT(ctx
);
1689 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
1690 _mesa_debug(ctx
, "glInvalidateTexSubImage %d\n", texture
);
1692 t
= invalidate_tex_image_error_check(ctx
, texture
, level
,
1693 "glInvalidateTexSubImage");
1695 /* The GL_ARB_invalidate_subdata spec says:
1697 * "...the specified subregion must be between -<b> and <dim>+<b> where
1698 * <dim> is the size of the dimension of the texture image, and <b> is
1699 * the size of the border of that texture image, otherwise
1700 * INVALID_VALUE is generated (border is not applied to dimensions that
1701 * don't exist in a given texture target)."
1703 image
= t
->Image
[0][level
];
1712 /* The GL_ARB_invalidate_subdata spec says:
1714 * "For texture targets that don't have certain dimensions, this
1715 * command treats those dimensions as having a size of 1. For
1716 * example, to invalidate a portion of a two-dimensional texture,
1717 * the application would use <zoffset> equal to zero and <depth>
1720 switch (t
->Target
) {
1721 case GL_TEXTURE_BUFFER
:
1730 xBorder
= image
->Border
;
1733 imageWidth
= image
->Width
;
1737 case GL_TEXTURE_1D_ARRAY
:
1738 xBorder
= image
->Border
;
1741 imageWidth
= image
->Width
;
1742 imageHeight
= image
->Height
;
1746 case GL_TEXTURE_CUBE_MAP
:
1747 case GL_TEXTURE_RECTANGLE
:
1748 case GL_TEXTURE_2D_MULTISAMPLE
:
1749 xBorder
= image
->Border
;
1750 yBorder
= image
->Border
;
1752 imageWidth
= image
->Width
;
1753 imageHeight
= image
->Height
;
1756 case GL_TEXTURE_2D_ARRAY
:
1757 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1758 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY
:
1759 xBorder
= image
->Border
;
1760 yBorder
= image
->Border
;
1762 imageWidth
= image
->Width
;
1763 imageHeight
= image
->Height
;
1764 imageDepth
= image
->Depth
;
1767 xBorder
= image
->Border
;
1768 yBorder
= image
->Border
;
1769 zBorder
= image
->Border
;
1770 imageWidth
= image
->Width
;
1771 imageHeight
= image
->Height
;
1772 imageDepth
= image
->Depth
;
1775 assert(!"Should not get here.");
1785 if (xoffset
< -xBorder
) {
1786 _mesa_error(ctx
, GL_INVALID_VALUE
, "glInvalidateSubTexImage(xoffset)");
1790 if (xoffset
+ width
> imageWidth
+ xBorder
) {
1791 _mesa_error(ctx
, GL_INVALID_VALUE
,
1792 "glInvalidateSubTexImage(xoffset+width)");
1796 if (yoffset
< -yBorder
) {
1797 _mesa_error(ctx
, GL_INVALID_VALUE
, "glInvalidateSubTexImage(yoffset)");
1801 if (yoffset
+ height
> imageHeight
+ yBorder
) {
1802 _mesa_error(ctx
, GL_INVALID_VALUE
,
1803 "glInvalidateSubTexImage(yoffset+height)");
1807 if (zoffset
< -zBorder
) {
1808 _mesa_error(ctx
, GL_INVALID_VALUE
,
1809 "glInvalidateSubTexImage(zoffset)");
1813 if (zoffset
+ depth
> imageDepth
+ zBorder
) {
1814 _mesa_error(ctx
, GL_INVALID_VALUE
,
1815 "glInvalidateSubTexImage(zoffset+depth)");
1820 /* We don't actually do anything for this yet. Just return after
1821 * validating the parameters and generating the required errors.
1827 _mesa_InvalidateTexImage(GLuint texture
, GLint level
)
1829 GET_CURRENT_CONTEXT(ctx
);
1831 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
1832 _mesa_debug(ctx
, "glInvalidateTexImage(%d, %d)\n", texture
, level
);
1834 invalidate_tex_image_error_check(ctx
, texture
, level
,
1835 "glInvalidateTexImage");
1837 /* We don't actually do anything for this yet. Just return after
1838 * validating the parameters and generating the required errors.