[QMGRPRXY]
[reactos.git] / reactos / dll / opengl / mesa / main / teximage.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * \file teximage.c
28 * Texture image-related functions.
29 */
30
31 #include <precomp.h>
32
33 /**
34 * State changes which we care about for glCopyTex[Sub]Image() calls.
35 * In particular, we care about pixel transfer state and buffer state
36 * (such as glReadBuffer to make sure we read from the right renderbuffer).
37 */
38 #define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL)
39
40
41
42 /**
43 * Return the simple base format for a given internal texture format.
44 * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
45 *
46 * \param ctx GL context.
47 * \param internalFormat the internal texture format token or 1, 2, 3, or 4.
48 *
49 * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
50 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum.
51 *
52 * This is the format which is used during texture application (i.e. the
53 * texture format and env mode determine the arithmetic used.
54 *
55 * XXX this could be static
56 */
57 GLint
58 _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
59 {
60 switch (internalFormat) {
61 case GL_ALPHA:
62 case GL_ALPHA4:
63 case GL_ALPHA8:
64 case GL_ALPHA12:
65 case GL_ALPHA16:
66 return GL_ALPHA;
67 case 1:
68 case GL_LUMINANCE:
69 case GL_LUMINANCE4:
70 case GL_LUMINANCE8:
71 case GL_LUMINANCE12:
72 case GL_LUMINANCE16:
73 return GL_LUMINANCE;
74 case 2:
75 case GL_LUMINANCE_ALPHA:
76 case GL_LUMINANCE4_ALPHA4:
77 case GL_LUMINANCE6_ALPHA2:
78 case GL_LUMINANCE8_ALPHA8:
79 case GL_LUMINANCE12_ALPHA4:
80 case GL_LUMINANCE12_ALPHA12:
81 case GL_LUMINANCE16_ALPHA16:
82 return GL_LUMINANCE_ALPHA;
83 case GL_INTENSITY:
84 case GL_INTENSITY4:
85 case GL_INTENSITY8:
86 case GL_INTENSITY12:
87 case GL_INTENSITY16:
88 return GL_INTENSITY;
89 case 3:
90 case GL_RGB:
91 case GL_R3_G3_B2:
92 case GL_RGB4:
93 case GL_RGB5:
94 case GL_RGB8:
95 case GL_RGB10:
96 case GL_RGB12:
97 case GL_RGB16:
98 return GL_RGB;
99 case 4:
100 case GL_RGBA:
101 case GL_RGBA2:
102 case GL_RGBA4:
103 case GL_RGB5_A1:
104 case GL_RGBA8:
105 case GL_RGB10_A2:
106 case GL_RGBA12:
107 case GL_RGBA16:
108 return GL_RGBA;
109 default:
110 ; /* fallthrough */
111 }
112
113 if (ctx->Extensions.MESA_ycbcr_texture) {
114 if (internalFormat == GL_YCBCR_MESA)
115 return GL_YCBCR_MESA;
116 }
117
118 if (ctx->Extensions.ARB_texture_float) {
119 switch (internalFormat) {
120 case GL_ALPHA16F_ARB:
121 case GL_ALPHA32F_ARB:
122 return GL_ALPHA;
123 case GL_RGBA16F_ARB:
124 case GL_RGBA32F_ARB:
125 return GL_RGBA;
126 case GL_RGB16F_ARB:
127 case GL_RGB32F_ARB:
128 return GL_RGB;
129 case GL_INTENSITY16F_ARB:
130 case GL_INTENSITY32F_ARB:
131 return GL_INTENSITY;
132 case GL_LUMINANCE16F_ARB:
133 case GL_LUMINANCE32F_ARB:
134 return GL_LUMINANCE;
135 case GL_LUMINANCE_ALPHA16F_ARB:
136 case GL_LUMINANCE_ALPHA32F_ARB:
137 return GL_LUMINANCE_ALPHA;
138 default:
139 ; /* fallthrough */
140 }
141 }
142
143 if (ctx->VersionMajor >= 3 ||
144 ctx->Extensions.EXT_texture_integer) {
145 switch (internalFormat) {
146 case GL_RGBA8UI_EXT:
147 case GL_RGBA16UI_EXT:
148 case GL_RGBA32UI_EXT:
149 case GL_RGBA8I_EXT:
150 case GL_RGBA16I_EXT:
151 case GL_RGBA32I_EXT:
152 case GL_RGB10_A2UI:
153 return GL_RGBA;
154 case GL_RGB8UI_EXT:
155 case GL_RGB16UI_EXT:
156 case GL_RGB32UI_EXT:
157 case GL_RGB8I_EXT:
158 case GL_RGB16I_EXT:
159 case GL_RGB32I_EXT:
160 return GL_RGB;
161 }
162 }
163
164 if (ctx->Extensions.EXT_texture_integer) {
165 switch (internalFormat) {
166 case GL_ALPHA8UI_EXT:
167 case GL_ALPHA16UI_EXT:
168 case GL_ALPHA32UI_EXT:
169 case GL_ALPHA8I_EXT:
170 case GL_ALPHA16I_EXT:
171 case GL_ALPHA32I_EXT:
172 return GL_ALPHA;
173 case GL_INTENSITY8UI_EXT:
174 case GL_INTENSITY16UI_EXT:
175 case GL_INTENSITY32UI_EXT:
176 case GL_INTENSITY8I_EXT:
177 case GL_INTENSITY16I_EXT:
178 case GL_INTENSITY32I_EXT:
179 return GL_INTENSITY;
180 case GL_LUMINANCE8UI_EXT:
181 case GL_LUMINANCE16UI_EXT:
182 case GL_LUMINANCE32UI_EXT:
183 case GL_LUMINANCE8I_EXT:
184 case GL_LUMINANCE16I_EXT:
185 case GL_LUMINANCE32I_EXT:
186 return GL_LUMINANCE;
187 case GL_LUMINANCE_ALPHA8UI_EXT:
188 case GL_LUMINANCE_ALPHA16UI_EXT:
189 case GL_LUMINANCE_ALPHA32UI_EXT:
190 case GL_LUMINANCE_ALPHA8I_EXT:
191 case GL_LUMINANCE_ALPHA16I_EXT:
192 case GL_LUMINANCE_ALPHA32I_EXT:
193 return GL_LUMINANCE_ALPHA;
194 default:
195 ; /* fallthrough */
196 }
197 }
198
199 return -1; /* error */
200 }
201
202
203 /**
204 * Is the given texture format a generic compressed format?
205 */
206
207
208 /**
209 * For cube map faces, return a face index in [0,5].
210 * For other targets return 0;
211 */
212 GLuint
213 _mesa_tex_target_to_face(GLenum target)
214 {
215 if (_mesa_is_cube_face(target))
216 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
217 else
218 return 0;
219 }
220
221
222
223 /**
224 * Install gl_texture_image in a gl_texture_object according to the target
225 * and level parameters.
226 *
227 * \param tObj texture object.
228 * \param target texture target.
229 * \param level image level.
230 * \param texImage texture image.
231 */
232 static void
233 set_tex_image(struct gl_texture_object *tObj,
234 GLenum target, GLint level,
235 struct gl_texture_image *texImage)
236 {
237 const GLuint face = _mesa_tex_target_to_face(target);
238
239 ASSERT(tObj);
240 ASSERT(texImage);
241
242 tObj->Image[face][level] = texImage;
243
244 /* Set the 'back' pointer */
245 texImage->TexObject = tObj;
246 texImage->Level = level;
247 texImage->Face = face;
248 }
249
250
251 /**
252 * Allocate a texture image structure.
253 *
254 * Called via ctx->Driver.NewTextureImage() unless overriden by a device
255 * driver.
256 *
257 * \return a pointer to gl_texture_image struct with all fields initialized to
258 * zero.
259 */
260 struct gl_texture_image *
261 _mesa_new_texture_image( struct gl_context *ctx )
262 {
263 (void) ctx;
264 return CALLOC_STRUCT(gl_texture_image);
265 }
266
267
268 /**
269 * Free a gl_texture_image and associated data.
270 * This function is a fallback called via ctx->Driver.DeleteTextureImage().
271 *
272 * \param texImage texture image.
273 *
274 * Free the texture image structure and the associated image data.
275 */
276 void
277 _mesa_delete_texture_image(struct gl_context *ctx,
278 struct gl_texture_image *texImage)
279 {
280 /* Free texImage->Data and/or any other driver-specific texture
281 * image storage.
282 */
283 ASSERT(ctx->Driver.FreeTextureImageBuffer);
284 ctx->Driver.FreeTextureImageBuffer( ctx, texImage );
285 free(texImage);
286 }
287
288
289 /**
290 * Test if a target is a proxy target.
291 *
292 * \param target texture target.
293 *
294 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
295 */
296 GLboolean
297 _mesa_is_proxy_texture(GLenum target)
298 {
299 /*
300 * NUM_TEXTURE_TARGETS should match number of terms below, except there's no
301 * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES.
302 */
303 assert(NUM_TEXTURE_TARGETS == 7 + 2);
304
305 return (target == GL_PROXY_TEXTURE_1D ||
306 target == GL_PROXY_TEXTURE_2D ||
307 target == GL_PROXY_TEXTURE_3D ||
308 target == GL_PROXY_TEXTURE_CUBE_MAP_ARB);
309 }
310
311
312 /**
313 * Return the proxy target which corresponds to the given texture target
314 */
315 static GLenum
316 get_proxy_target(GLenum target)
317 {
318 switch (target) {
319 case GL_TEXTURE_1D:
320 case GL_PROXY_TEXTURE_1D:
321 return GL_PROXY_TEXTURE_1D;
322 case GL_TEXTURE_2D:
323 case GL_PROXY_TEXTURE_2D:
324 return GL_PROXY_TEXTURE_2D;
325 case GL_TEXTURE_3D:
326 case GL_PROXY_TEXTURE_3D:
327 return GL_PROXY_TEXTURE_3D;
328 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
329 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
330 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
331 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
332 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
333 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
334 case GL_TEXTURE_CUBE_MAP_ARB:
335 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
336 return GL_PROXY_TEXTURE_CUBE_MAP_ARB;
337 default:
338 _mesa_problem(NULL, "unexpected target in get_proxy_target()");
339 return 0;
340 }
341 }
342
343
344 /**
345 * Get the texture object that corresponds to the target of the given
346 * texture unit. The target should have already been checked for validity.
347 *
348 * \param ctx GL context.
349 * \param texUnit texture unit.
350 * \param target texture target.
351 *
352 * \return pointer to the texture object on success, or NULL on failure.
353 */
354 struct gl_texture_object *
355 _mesa_select_tex_object(struct gl_context *ctx,
356 GLenum target)
357 {
358 switch (target) {
359 case GL_TEXTURE_1D:
360 return ctx->Texture.Unit.CurrentTex[TEXTURE_1D_INDEX];
361 case GL_PROXY_TEXTURE_1D:
362 return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
363 case GL_TEXTURE_2D:
364 return ctx->Texture.Unit.CurrentTex[TEXTURE_2D_INDEX];
365 case GL_PROXY_TEXTURE_2D:
366 return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
367 case GL_TEXTURE_3D:
368 return ctx->Texture.Unit.CurrentTex[TEXTURE_3D_INDEX];
369 case GL_PROXY_TEXTURE_3D:
370 return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
371 default:
372 _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
373 return NULL;
374 }
375 }
376
377
378 /**
379 * Get a texture image pointer from a texture object, given a texture
380 * target and mipmap level. The target and level parameters should
381 * have already been error-checked.
382 *
383 * \param ctx GL context.
384 * \param texObj texture unit.
385 * \param target texture target.
386 * \param level image level.
387 *
388 * \return pointer to the texture image structure, or NULL on failure.
389 */
390 struct gl_texture_image *
391 _mesa_select_tex_image(struct gl_context *ctx,
392 const struct gl_texture_object *texObj,
393 GLenum target, GLint level)
394 {
395 const GLuint face = _mesa_tex_target_to_face(target);
396
397 ASSERT(texObj);
398 ASSERT(level >= 0);
399 ASSERT(level < MAX_TEXTURE_LEVELS);
400
401 return texObj->Image[face][level];
402 }
403
404
405 /**
406 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
407 * it and install it. Only return NULL if passed a bad parameter or run
408 * out of memory.
409 */
410 struct gl_texture_image *
411 _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
412 GLenum target, GLint level)
413 {
414 struct gl_texture_image *texImage;
415
416 if (!texObj)
417 return NULL;
418
419 texImage = _mesa_select_tex_image(ctx, texObj, target, level);
420 if (!texImage) {
421 texImage = ctx->Driver.NewTextureImage(ctx);
422 if (!texImage) {
423 _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
424 return NULL;
425 }
426
427 set_tex_image(texObj, target, level, texImage);
428 }
429
430 return texImage;
431 }
432
433
434 /**
435 * Return pointer to the specified proxy texture image.
436 * Note that proxy textures are per-context, not per-texture unit.
437 * \return pointer to texture image or NULL if invalid target, invalid
438 * level, or out of memory.
439 */
440 struct gl_texture_image *
441 _mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
442 {
443 struct gl_texture_image *texImage;
444 GLuint texIndex;
445
446 if (level < 0 )
447 return NULL;
448
449 switch (target) {
450 case GL_PROXY_TEXTURE_1D:
451 if (level >= ctx->Const.MaxTextureLevels)
452 return NULL;
453 texIndex = TEXTURE_1D_INDEX;
454 break;
455 case GL_PROXY_TEXTURE_2D:
456 if (level >= ctx->Const.MaxTextureLevels)
457 return NULL;
458 texIndex = TEXTURE_2D_INDEX;
459 break;
460 case GL_PROXY_TEXTURE_3D:
461 if (level >= ctx->Const.Max3DTextureLevels)
462 return NULL;
463 texIndex = TEXTURE_3D_INDEX;
464 break;
465 case GL_PROXY_TEXTURE_CUBE_MAP:
466 if (level >= ctx->Const.MaxCubeTextureLevels)
467 return NULL;
468 texIndex = TEXTURE_CUBE_INDEX;
469 break;
470 default:
471 return NULL;
472 }
473
474 texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level];
475 if (!texImage) {
476 texImage = ctx->Driver.NewTextureImage(ctx);
477 if (!texImage) {
478 _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
479 return NULL;
480 }
481 ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage;
482 /* Set the 'back' pointer */
483 texImage->TexObject = ctx->Texture.ProxyTex[texIndex];
484 }
485 return texImage;
486 }
487
488
489 /**
490 * Get the maximum number of allowed mipmap levels.
491 *
492 * \param ctx GL context.
493 * \param target texture target.
494 *
495 * \return the maximum number of allowed mipmap levels for the given
496 * texture target, or zero if passed a bad target.
497 *
498 * \sa gl_constants.
499 */
500 GLint
501 _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
502 {
503 switch (target) {
504 case GL_TEXTURE_1D:
505 case GL_PROXY_TEXTURE_1D:
506 case GL_TEXTURE_2D:
507 case GL_PROXY_TEXTURE_2D:
508 return ctx->Const.MaxTextureLevels;
509 case GL_TEXTURE_3D:
510 case GL_PROXY_TEXTURE_3D:
511 return ctx->Const.Max3DTextureLevels;
512 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
513 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
514 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
515 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
516 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
517 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
518 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
519 return ctx->Extensions.ARB_texture_cube_map
520 ? ctx->Const.MaxCubeTextureLevels : 0;
521 default:
522 return 0; /* bad target */
523 }
524 }
525
526
527 /**
528 * Return number of dimensions per mipmap level for the given texture target.
529 */
530 GLint
531 _mesa_get_texture_dimensions(GLenum target)
532 {
533 switch (target) {
534 case GL_TEXTURE_1D:
535 case GL_PROXY_TEXTURE_1D:
536 return 1;
537 case GL_TEXTURE_2D:
538 case GL_TEXTURE_CUBE_MAP:
539 case GL_PROXY_TEXTURE_2D:
540 case GL_PROXY_TEXTURE_CUBE_MAP:
541 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
542 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
543 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
544 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
545 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
546 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
547 return 2;
548 case GL_TEXTURE_3D:
549 case GL_PROXY_TEXTURE_3D:
550 return 3;
551 default:
552 _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()",
553 target);
554 return 2;
555 }
556 }
557
558
559
560
561 #if 000 /* not used anymore */
562 /*
563 * glTexImage[123]D can accept a NULL image pointer. In this case we
564 * create a texture image with unspecified image contents per the OpenGL
565 * spec.
566 */
567 static GLubyte *
568 make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
569 {
570 const GLint components = _mesa_components_in_format(format);
571 const GLint numPixels = width * height * depth;
572 GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
573
574 #ifdef DEBUG
575 /*
576 * Let's see if anyone finds this. If glTexImage2D() is called with
577 * a NULL image pointer then load the texture image with something
578 * interesting instead of leaving it indeterminate.
579 */
580 if (data) {
581 static const char message[8][32] = {
582 " X X XXXXX XXX X ",
583 " XX XX X X X X X ",
584 " X X X X X X X ",
585 " X X XXXX XXX XXXXX ",
586 " X X X X X X ",
587 " X X X X X X X ",
588 " X X XXXXX XXX X X ",
589 " "
590 };
591
592 GLubyte *imgPtr = data;
593 GLint h, i, j, k;
594 for (h = 0; h < depth; h++) {
595 for (i = 0; i < height; i++) {
596 GLint srcRow = 7 - (i % 8);
597 for (j = 0; j < width; j++) {
598 GLint srcCol = j % 32;
599 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
600 for (k = 0; k < components; k++) {
601 *imgPtr++ = texel;
602 }
603 }
604 }
605 }
606 }
607 #endif
608
609 return data;
610 }
611 #endif
612
613
614
615 /**
616 * Set the size and format-related fields of a gl_texture_image struct
617 * to zero. This is used when a proxy texture test fails.
618 */
619 static void
620 clear_teximage_fields(struct gl_texture_image *img)
621 {
622 ASSERT(img);
623 img->_BaseFormat = 0;
624 img->InternalFormat = 0;
625 img->Border = 0;
626 img->Width = 0;
627 img->Height = 0;
628 img->Depth = 0;
629 img->Width2 = 0;
630 img->Height2 = 0;
631 img->Depth2 = 0;
632 img->WidthLog2 = 0;
633 img->HeightLog2 = 0;
634 img->DepthLog2 = 0;
635 img->TexFormat = MESA_FORMAT_NONE;
636 }
637
638
639 /**
640 * Initialize basic fields of the gl_texture_image struct.
641 *
642 * \param ctx GL context.
643 * \param img texture image structure to be initialized.
644 * \param width image width.
645 * \param height image height.
646 * \param depth image depth.
647 * \param border image border.
648 * \param internalFormat internal format.
649 * \param format the actual hardware format (one of MESA_FORMAT_*)
650 *
651 * Fills in the fields of \p img with the given information.
652 * Note: width, height and depth include the border.
653 */
654 void
655 _mesa_init_teximage_fields(struct gl_context *ctx,
656 struct gl_texture_image *img,
657 GLsizei width, GLsizei height, GLsizei depth,
658 GLint border, GLenum internalFormat,
659 gl_format format)
660 {
661 GLenum target;
662 ASSERT(img);
663 ASSERT(width >= 0);
664 ASSERT(height >= 0);
665 ASSERT(depth >= 0);
666
667 target = img->TexObject->Target;
668 img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat );
669 ASSERT(img->_BaseFormat > 0);
670 img->InternalFormat = internalFormat;
671 img->Border = border;
672 img->Width = width;
673 img->Height = height;
674 img->Depth = depth;
675
676 img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */
677 img->WidthLog2 = _mesa_logbase2(img->Width2);
678
679 switch(target) {
680 case GL_TEXTURE_1D:
681 case GL_PROXY_TEXTURE_1D:
682 if (height == 0)
683 img->Height2 = 0;
684 else
685 img->Height2 = 1;
686 img->HeightLog2 = 0;
687 if (depth == 0)
688 img->Depth2 = 0;
689 else
690 img->Depth2 = 1;
691 img->DepthLog2 = 0;
692 break;
693 case GL_TEXTURE_2D:
694 case GL_TEXTURE_CUBE_MAP:
695 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
696 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
697 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
698 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
699 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
700 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
701 case GL_PROXY_TEXTURE_2D:
702 case GL_PROXY_TEXTURE_CUBE_MAP:
703 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
704 img->HeightLog2 = _mesa_logbase2(img->Height2);
705 if (depth == 0)
706 img->Depth2 = 0;
707 else
708 img->Depth2 = 1;
709 img->DepthLog2 = 0;
710 break;
711 case GL_TEXTURE_3D:
712 case GL_PROXY_TEXTURE_3D:
713 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
714 img->HeightLog2 = _mesa_logbase2(img->Height2);
715 img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */
716 img->DepthLog2 = _mesa_logbase2(img->Depth2);
717 break;
718 default:
719 _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()",
720 target);
721 }
722
723 img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
724 img->TexFormat = format;
725 }
726
727
728 /**
729 * Free and clear fields of the gl_texture_image struct.
730 *
731 * \param ctx GL context.
732 * \param texImage texture image structure to be cleared.
733 *
734 * After the call, \p texImage will have no data associated with it. Its
735 * fields are cleared so that its parent object will test incomplete.
736 */
737 void
738 _mesa_clear_texture_image(struct gl_context *ctx,
739 struct gl_texture_image *texImage)
740 {
741 ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
742 clear_teximage_fields(texImage);
743 }
744
745
746 /**
747 * This is the fallback for Driver.TestProxyTexImage(). Test the texture
748 * level, width, height and depth against the ctx->Const limits for textures.
749 *
750 * A hardware driver might override this function if, for example, the
751 * max 3D texture size is 512x512x64 (i.e. not a cube).
752 *
753 * Note that width, height, depth == 0 is not an error. However, a
754 * texture with zero width/height/depth will be considered "incomplete"
755 * and texturing will effectively be disabled.
756 *
757 * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
758 * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
759 * GL_PROXY_TEXTURE_CUBE_MAP_ARB.
760 * \param level as passed to glTexImage
761 * \param internalFormat as passed to glTexImage
762 * \param format as passed to glTexImage
763 * \param type as passed to glTexImage
764 * \param width as passed to glTexImage
765 * \param height as passed to glTexImage
766 * \param depth as passed to glTexImage
767 * \param border as passed to glTexImage
768 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
769 */
770 GLboolean
771 _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
772 GLint internalFormat, GLenum format, GLenum type,
773 GLint width, GLint height, GLint depth, GLint border)
774 {
775 GLint maxSize;
776
777 (void) internalFormat;
778 (void) format;
779 (void) type;
780
781 switch (target) {
782 case GL_PROXY_TEXTURE_1D:
783 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
784 if (width < 2 * border || width > 2 * border + maxSize)
785 return GL_FALSE;
786 if (level >= ctx->Const.MaxTextureLevels)
787 return GL_FALSE;
788 if (!ctx->Extensions.ARB_texture_non_power_of_two) {
789 if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
790 return GL_FALSE;
791 }
792 return GL_TRUE;
793
794 case GL_PROXY_TEXTURE_2D:
795 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
796 if (width < 2 * border || width > 2 * border + maxSize)
797 return GL_FALSE;
798 if (height < 2 * border || height > 2 * border + maxSize)
799 return GL_FALSE;
800 if (level >= ctx->Const.MaxTextureLevels)
801 return GL_FALSE;
802 if (!ctx->Extensions.ARB_texture_non_power_of_two) {
803 if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
804 return GL_FALSE;
805 if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
806 return GL_FALSE;
807 }
808 return GL_TRUE;
809
810 case GL_PROXY_TEXTURE_3D:
811 maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
812 if (width < 2 * border || width > 2 * border + maxSize)
813 return GL_FALSE;
814 if (height < 2 * border || height > 2 * border + maxSize)
815 return GL_FALSE;
816 if (depth < 2 * border || depth > 2 * border + maxSize)
817 return GL_FALSE;
818 if (level >= ctx->Const.Max3DTextureLevels)
819 return GL_FALSE;
820 if (!ctx->Extensions.ARB_texture_non_power_of_two) {
821 if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
822 return GL_FALSE;
823 if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
824 return GL_FALSE;
825 if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border))
826 return GL_FALSE;
827 }
828 return GL_TRUE;
829
830 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
831 maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
832 if (width < 2 * border || width > 2 * border + maxSize)
833 return GL_FALSE;
834 if (height < 2 * border || height > 2 * border + maxSize)
835 return GL_FALSE;
836 if (level >= ctx->Const.MaxCubeTextureLevels)
837 return GL_FALSE;
838 if (!ctx->Extensions.ARB_texture_non_power_of_two) {
839 if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
840 return GL_FALSE;
841 if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
842 return GL_FALSE;
843 }
844 return GL_TRUE;
845
846 default:
847 _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
848 return GL_FALSE;
849 }
850 }
851
852
853 /**
854 * Check if the memory used by the texture would exceed the driver's limit.
855 * This lets us support a max 3D texture size of 8K (for example) but
856 * prevents allocating a full 8K x 8K x 8K texture.
857 * XXX this could be rolled into the proxy texture size test (above) but
858 * we don't have the actual texture internal format at that point.
859 */
860 static GLboolean
861 legal_texture_size(struct gl_context *ctx, gl_format format,
862 GLint width, GLint height, GLint depth)
863 {
864 uint64_t bytes = _mesa_format_image_size64(format, width, height, depth);
865 uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */
866 return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
867 }
868
869 /**
870 * Check if the given texture target value is legal for a
871 * glTexImage1/2/3D call.
872 */
873 static GLboolean
874 legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
875 {
876 switch (dims) {
877 case 1:
878 switch (target) {
879 case GL_TEXTURE_1D:
880 case GL_PROXY_TEXTURE_1D:
881 return GL_TRUE;
882 default:
883 return GL_FALSE;
884 }
885 case 2:
886 switch (target) {
887 case GL_TEXTURE_2D:
888 case GL_PROXY_TEXTURE_2D:
889 return GL_TRUE;
890 case GL_PROXY_TEXTURE_CUBE_MAP:
891 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
892 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
893 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
894 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
895 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
896 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
897 return ctx->Extensions.ARB_texture_cube_map;
898 default:
899 return GL_FALSE;
900 }
901 case 3:
902 switch (target) {
903 case GL_TEXTURE_3D:
904 case GL_PROXY_TEXTURE_3D:
905 return GL_TRUE;
906 default:
907 return GL_FALSE;
908 }
909 default:
910 _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims);
911 return GL_FALSE;
912 }
913 }
914
915
916 /**
917 * Check if the given texture target value is legal for a
918 * glTexSubImage, glCopyTexSubImage or glCopyTexImage call.
919 * The difference compared to legal_teximage_target() above is that
920 * proxy targets are not supported.
921 */
922 static GLboolean
923 legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
924 {
925 switch (dims) {
926 case 1:
927 return target == GL_TEXTURE_1D;
928 case 2:
929 switch (target) {
930 case GL_TEXTURE_2D:
931 return GL_TRUE;
932 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
933 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
934 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
935 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
936 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
937 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
938 return ctx->Extensions.ARB_texture_cube_map;
939 default:
940 return GL_FALSE;
941 }
942 case 3:
943 switch (target) {
944 case GL_TEXTURE_3D:
945 return GL_TRUE;
946 default:
947 return GL_FALSE;
948 }
949 default:
950 _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()",
951 dims);
952 return GL_FALSE;
953 }
954 }
955
956
957 /**
958 * Helper function to determine if a texture object is mutable (in terms
959 * of GL_ARB_texture_storage).
960 */
961 static GLboolean
962 mutable_tex_object(struct gl_context *ctx, GLenum target)
963 {
964 if (ctx->Extensions.ARB_texture_storage) {
965 struct gl_texture_object *texObj =
966 _mesa_select_tex_object(ctx, target);
967 return !texObj->Immutable;
968 }
969 return GL_TRUE;
970 }
971
972
973
974 /**
975 * Test the glTexImage[123]D() parameters for errors.
976 *
977 * \param ctx GL context.
978 * \param dimensions texture image dimensions (must be 1, 2 or 3).
979 * \param target texture target given by the user.
980 * \param level image level given by the user.
981 * \param internalFormat internal format given by the user.
982 * \param format pixel data format given by the user.
983 * \param type pixel data type given by the user.
984 * \param width image width given by the user.
985 * \param height image height given by the user.
986 * \param depth image depth given by the user.
987 * \param border image border given by the user.
988 *
989 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
990 *
991 * Verifies each of the parameters against the constants specified in
992 * __struct gl_contextRec::Const and the supported extensions, and according
993 * to the OpenGL specification.
994 */
995 static GLboolean
996 texture_error_check( struct gl_context *ctx,
997 GLuint dimensions, GLenum target,
998 GLint level, GLint internalFormat,
999 GLenum format, GLenum type,
1000 GLint width, GLint height,
1001 GLint depth, GLint border )
1002 {
1003 const GLenum proxyTarget = get_proxy_target(target);
1004 const GLboolean isProxy = target == proxyTarget;
1005 GLboolean sizeOK = GL_TRUE;
1006 GLboolean colorFormat;
1007 GLenum err;
1008
1009 /* Even though there are no color-index textures, we still have to support
1010 * uploading color-index data and remapping it to RGB via the
1011 * GL_PIXEL_MAP_I_TO_[RGBA] tables.
1012 */
1013 const GLboolean indexFormat = (format == GL_COLOR_INDEX);
1014
1015 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
1016 if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1017 if (!isProxy) {
1018 _mesa_error(ctx, GL_INVALID_VALUE,
1019 "glTexImage%dD(level=%d)", dimensions, level);
1020 }
1021 return GL_TRUE;
1022 }
1023
1024 /* Check border */
1025 if (border < 0 || border > 1) {
1026 if (!isProxy) {
1027 _mesa_error(ctx, GL_INVALID_VALUE,
1028 "glTexImage%dD(border=%d)", dimensions, border);
1029 }
1030 return GL_TRUE;
1031 }
1032
1033 if (width < 0 || height < 0 || depth < 0) {
1034 if (!isProxy) {
1035 _mesa_error(ctx, GL_INVALID_VALUE,
1036 "glTexImage%dD(width, height or depth < 0)", dimensions);
1037 }
1038 return GL_TRUE;
1039 }
1040
1041 /* Do this simple check before calling the TestProxyTexImage() function */
1042 if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
1043 sizeOK = (width == height);
1044 }
1045
1046 /*
1047 * Use the proxy texture driver hook to see if the size/level/etc are
1048 * legal.
1049 */
1050 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
1051 internalFormat, format,
1052 type, width, height,
1053 depth, border);
1054 if (!sizeOK) {
1055 if (!isProxy) {
1056 _mesa_error(ctx, GL_INVALID_VALUE,
1057 "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
1058 dimensions, level, width, height, depth);
1059 }
1060 return GL_TRUE;
1061 }
1062
1063 /* Check internalFormat */
1064 if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
1065 if (!isProxy) {
1066 _mesa_error(ctx, GL_INVALID_VALUE,
1067 "glTexImage%dD(internalFormat=%s)",
1068 dimensions, _mesa_lookup_enum_by_nr(internalFormat));
1069 }
1070 return GL_TRUE;
1071 }
1072
1073 /* Check incoming image format and type */
1074 err = _mesa_error_check_format_and_type(ctx, format, type);
1075 if (err != GL_NO_ERROR) {
1076 if (!isProxy) {
1077 _mesa_error(ctx, err,
1078 "glTexImage%dD(incompatible format 0x%x, type 0x%x)",
1079 dimensions, format, type);
1080 }
1081 return GL_TRUE;
1082 }
1083
1084 /* make sure internal format and format basically agree */
1085 colorFormat = _mesa_is_color_format(format);
1086 if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
1087 (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
1088 (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format))) {
1089 if (!isProxy)
1090 _mesa_error(ctx, GL_INVALID_OPERATION,
1091 "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
1092 dimensions, internalFormat, format);
1093 return GL_TRUE;
1094 }
1095
1096 /* additional checks for ycbcr textures */
1097 if (internalFormat == GL_YCBCR_MESA) {
1098 ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1099 if (type != GL_UNSIGNED_SHORT_8_8_MESA &&
1100 type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
1101 char message[100];
1102 _mesa_snprintf(message, sizeof(message),
1103 "glTexImage%dD(format/type YCBCR mismatch", dimensions);
1104 _mesa_error(ctx, GL_INVALID_ENUM, "%s", message);
1105 return GL_TRUE; /* error */
1106 }
1107 if (target != GL_TEXTURE_2D &&
1108 target != GL_PROXY_TEXTURE_2D) {
1109 if (!isProxy)
1110 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)");
1111 return GL_TRUE;
1112 }
1113 if (border != 0) {
1114 if (!isProxy) {
1115 char message[100];
1116 _mesa_snprintf(message, sizeof(message),
1117 "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)",
1118 dimensions, border);
1119 _mesa_error(ctx, GL_INVALID_VALUE, "%s", message);
1120 }
1121 return GL_TRUE;
1122 }
1123 }
1124
1125 /* additional checks for depth textures */
1126 if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
1127 /* Only 1D, 2D, rect, array and cube textures supported, not 3D
1128 * Cubemaps are only supported for GL version > 3.0 or with EXT_gpu_shader4 */
1129 if (target != GL_TEXTURE_1D &&
1130 target != GL_PROXY_TEXTURE_1D &&
1131 target != GL_TEXTURE_2D &&
1132 target != GL_PROXY_TEXTURE_2D &&
1133 !((_mesa_is_cube_face(target) || target == GL_PROXY_TEXTURE_CUBE_MAP) &&
1134 (ctx->VersionMajor >= 3))) {
1135 if (!isProxy)
1136 _mesa_error(ctx, GL_INVALID_ENUM,
1137 "glTexImage(target/internalFormat)");
1138 return GL_TRUE;
1139 }
1140 }
1141
1142 /* additional checks for integer textures */
1143 if ((ctx->VersionMajor >= 3 || ctx->Extensions.EXT_texture_integer) &&
1144 (_mesa_is_integer_format(format) !=
1145 _mesa_is_integer_format(internalFormat))) {
1146 if (!isProxy) {
1147 _mesa_error(ctx, GL_INVALID_OPERATION,
1148 "glTexImage%dD(integer/non-integer format mismatch)",
1149 dimensions);
1150 }
1151 return GL_TRUE;
1152 }
1153
1154 if (!mutable_tex_object(ctx, target)) {
1155 _mesa_error(ctx, GL_INVALID_OPERATION,
1156 "glTexImage%dD(immutable texture)", dimensions);
1157 return GL_TRUE;
1158 }
1159
1160 /* if we get here, the parameters are OK */
1161 return GL_FALSE;
1162 }
1163
1164
1165 /**
1166 * Test glTexSubImage[123]D() parameters for errors.
1167 *
1168 * \param ctx GL context.
1169 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1170 * \param target texture target given by the user.
1171 * \param level image level given by the user.
1172 * \param xoffset sub-image x offset given by the user.
1173 * \param yoffset sub-image y offset given by the user.
1174 * \param zoffset sub-image z offset given by the user.
1175 * \param format pixel data format given by the user.
1176 * \param type pixel data type given by the user.
1177 * \param width image width given by the user.
1178 * \param height image height given by the user.
1179 * \param depth image depth given by the user.
1180 *
1181 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1182 *
1183 * Verifies each of the parameters against the constants specified in
1184 * __struct gl_contextRec::Const and the supported extensions, and according
1185 * to the OpenGL specification.
1186 */
1187 static GLboolean
1188 subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
1189 GLenum target, GLint level,
1190 GLint xoffset, GLint yoffset, GLint zoffset,
1191 GLint width, GLint height, GLint depth,
1192 GLenum format, GLenum type )
1193 {
1194 GLenum err;
1195
1196 /* Basic level check */
1197 if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1198 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
1199 return GL_TRUE;
1200 }
1201
1202 /* Check for negative sizes */
1203 if (width < 0) {
1204 _mesa_error(ctx, GL_INVALID_VALUE,
1205 "glTexSubImage%dD(width=%d)", dimensions, width);
1206 return GL_TRUE;
1207 }
1208 if (height < 0 && dimensions > 1) {
1209 _mesa_error(ctx, GL_INVALID_VALUE,
1210 "glTexSubImage%dD(height=%d)", dimensions, height);
1211 return GL_TRUE;
1212 }
1213 if (depth < 0 && dimensions > 2) {
1214 _mesa_error(ctx, GL_INVALID_VALUE,
1215 "glTexSubImage%dD(depth=%d)", dimensions, depth);
1216 return GL_TRUE;
1217 }
1218
1219 err = _mesa_error_check_format_and_type(ctx, format, type);
1220 if (err != GL_NO_ERROR) {
1221 _mesa_error(ctx, err,
1222 "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)",
1223 dimensions, format, type);
1224 return GL_TRUE;
1225 }
1226
1227 return GL_FALSE;
1228 }
1229
1230
1231 /**
1232 * Do second part of glTexSubImage which depends on the destination texture.
1233 * \return GL_TRUE if error recorded, GL_FALSE otherwise
1234 */
1235 static GLboolean
1236 subtexture_error_check2( struct gl_context *ctx, GLuint dimensions,
1237 GLenum target, GLint level,
1238 GLint xoffset, GLint yoffset, GLint zoffset,
1239 GLint width, GLint height, GLint depth,
1240 GLenum format, GLenum type,
1241 const struct gl_texture_image *destTex )
1242 {
1243 if (!destTex) {
1244 /* undefined image level */
1245 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions);
1246 return GL_TRUE;
1247 }
1248
1249 if (xoffset < -((GLint)destTex->Border)) {
1250 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
1251 dimensions);
1252 return GL_TRUE;
1253 }
1254 if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
1255 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
1256 dimensions);
1257 return GL_TRUE;
1258 }
1259 if (dimensions > 1) {
1260 if (yoffset < -((GLint)destTex->Border)) {
1261 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
1262 dimensions);
1263 return GL_TRUE;
1264 }
1265 if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
1266 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
1267 dimensions);
1268 return GL_TRUE;
1269 }
1270 }
1271 if (dimensions > 2) {
1272 if (zoffset < -((GLint)destTex->Border)) {
1273 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
1274 return GL_TRUE;
1275 }
1276 if (zoffset + depth > (GLint) (destTex->Depth + destTex->Border)) {
1277 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
1278 return GL_TRUE;
1279 }
1280 }
1281
1282 if (ctx->VersionMajor >= 3 || ctx->Extensions.EXT_texture_integer) {
1283 /* both source and dest must be integer-valued, or neither */
1284 if (_mesa_is_format_integer_color(destTex->TexFormat) !=
1285 _mesa_is_integer_format(format)) {
1286 _mesa_error(ctx, GL_INVALID_OPERATION,
1287 "glTexSubImage%dD(integer/non-integer format mismatch)",
1288 dimensions);
1289 return GL_TRUE;
1290 }
1291 }
1292
1293 return GL_FALSE;
1294 }
1295
1296
1297 /**
1298 * Test glCopyTexImage[12]D() parameters for errors.
1299 *
1300 * \param ctx GL context.
1301 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1302 * \param target texture target given by the user.
1303 * \param level image level given by the user.
1304 * \param internalFormat internal format given by the user.
1305 * \param width image width given by the user.
1306 * \param height image height given by the user.
1307 * \param border texture border.
1308 *
1309 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1310 *
1311 * Verifies each of the parameters against the constants specified in
1312 * __struct gl_contextRec::Const and the supported extensions, and according
1313 * to the OpenGL specification.
1314 */
1315 static GLboolean
1316 copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
1317 GLenum target, GLint level, GLint internalFormat,
1318 GLint width, GLint height, GLint border )
1319 {
1320 const GLenum proxyTarget = get_proxy_target(target);
1321 const GLenum type = GL_FLOAT;
1322 GLboolean sizeOK;
1323 GLint baseFormat;
1324
1325 /* check target */
1326 if (!legal_texsubimage_target(ctx, dimensions, target)) {
1327 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
1328 dimensions, _mesa_lookup_enum_by_nr(target));
1329 return GL_TRUE;
1330 }
1331
1332 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
1333 if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1334 _mesa_error(ctx, GL_INVALID_VALUE,
1335 "glCopyTexImage%dD(level=%d)", dimensions, level);
1336 return GL_TRUE;
1337 }
1338
1339 /* Check border */
1340 if (border < 0 || border > 1) {
1341 return GL_TRUE;
1342 }
1343
1344 baseFormat = _mesa_base_tex_format(ctx, internalFormat);
1345 if (baseFormat < 0) {
1346 _mesa_error(ctx, GL_INVALID_VALUE,
1347 "glCopyTexImage%dD(internalFormat)", dimensions);
1348 return GL_TRUE;
1349 }
1350
1351 if (!_mesa_source_buffer_exists(ctx, baseFormat)) {
1352 _mesa_error(ctx, GL_INVALID_OPERATION,
1353 "glCopyTexImage%dD(missing readbuffer)", dimensions);
1354 return GL_TRUE;
1355 }
1356
1357 /* From the EXT_texture_integer spec:
1358 *
1359 * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage*
1360 * if the texture internalformat is an integer format and the read color
1361 * buffer is not an integer format, or if the internalformat is not an
1362 * integer format and the read color buffer is an integer format."
1363 */
1364 if (_mesa_is_color_format(internalFormat)) {
1365 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1366
1367 if (_mesa_is_integer_format(rb->InternalFormat) !=
1368 _mesa_is_integer_format(internalFormat)) {
1369 _mesa_error(ctx, GL_INVALID_OPERATION,
1370 "glCopyTexImage%dD(integer vs non-integer)", dimensions);
1371 return GL_TRUE;
1372 }
1373 }
1374
1375 /* Do size, level checking */
1376 sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB)
1377 ? (width == height) : 1;
1378
1379 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
1380 internalFormat, baseFormat,
1381 type, width, height,
1382 1, border);
1383
1384 if (!sizeOK) {
1385 if (dimensions == 1) {
1386 _mesa_error(ctx, GL_INVALID_VALUE,
1387 "glCopyTexImage1D(width=%d)", width);
1388 }
1389 else {
1390 ASSERT(dimensions == 2);
1391 _mesa_error(ctx, GL_INVALID_VALUE,
1392 "glCopyTexImage2D(width=%d, height=%d)", width, height);
1393 }
1394 return GL_TRUE;
1395 }
1396
1397 if (!mutable_tex_object(ctx, target)) {
1398 _mesa_error(ctx, GL_INVALID_OPERATION,
1399 "glCopyTexImage%dD(immutable texture)", dimensions);
1400 return GL_TRUE;
1401 }
1402
1403 /* if we get here, the parameters are OK */
1404 return GL_FALSE;
1405 }
1406
1407
1408 /**
1409 * Test glCopyTexSubImage[12]D() parameters for errors.
1410 * Note that this is the first part of error checking.
1411 * See also copytexsubimage_error_check2() below for the second part.
1412 *
1413 * \param ctx GL context.
1414 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1415 * \param target texture target given by the user.
1416 * \param level image level given by the user.
1417 *
1418 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1419 */
1420 static GLboolean
1421 copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
1422 GLenum target, GLint level)
1423 {
1424 /* check target (proxies not allowed) */
1425 if (!legal_texsubimage_target(ctx, dimensions, target)) {
1426 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)",
1427 dimensions, _mesa_lookup_enum_by_nr(target));
1428 return GL_TRUE;
1429 }
1430
1431 /* Check level */
1432 if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1433 _mesa_error(ctx, GL_INVALID_VALUE,
1434 "glCopyTexSubImage%dD(level=%d)", dimensions, level);
1435 return GL_TRUE;
1436 }
1437
1438 return GL_FALSE;
1439 }
1440
1441
1442 /**
1443 * Second part of error checking for glCopyTexSubImage[12]D().
1444 * \param xoffset sub-image x offset given by the user.
1445 * \param yoffset sub-image y offset given by the user.
1446 * \param zoffset sub-image z offset given by the user.
1447 * \param width image width given by the user.
1448 * \param height image height given by the user.
1449 */
1450 static GLboolean
1451 copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions,
1452 GLenum target, GLint level,
1453 GLint xoffset, GLint yoffset, GLint zoffset,
1454 GLsizei width, GLsizei height,
1455 const struct gl_texture_image *teximage )
1456 {
1457 /* check that dest tex image exists */
1458 if (!teximage) {
1459 _mesa_error(ctx, GL_INVALID_OPERATION,
1460 "glCopyTexSubImage%dD(undefined texture level: %d)",
1461 dimensions, level);
1462 return GL_TRUE;
1463 }
1464
1465 /* Check size */
1466 if (width < 0) {
1467 _mesa_error(ctx, GL_INVALID_VALUE,
1468 "glCopyTexSubImage%dD(width=%d)", dimensions, width);
1469 return GL_TRUE;
1470 }
1471 if (dimensions > 1 && height < 0) {
1472 _mesa_error(ctx, GL_INVALID_VALUE,
1473 "glCopyTexSubImage%dD(height=%d)", dimensions, height);
1474 return GL_TRUE;
1475 }
1476
1477 /* check x/y offsets */
1478 if (xoffset < -((GLint)teximage->Border)) {
1479 _mesa_error(ctx, GL_INVALID_VALUE,
1480 "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
1481 return GL_TRUE;
1482 }
1483 if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) {
1484 _mesa_error(ctx, GL_INVALID_VALUE,
1485 "glCopyTexSubImage%dD(xoffset+width)", dimensions);
1486 return GL_TRUE;
1487 }
1488 if (dimensions > 1) {
1489 if (yoffset < -((GLint)teximage->Border)) {
1490 _mesa_error(ctx, GL_INVALID_VALUE,
1491 "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
1492 return GL_TRUE;
1493 }
1494 /* NOTE: we're adding the border here, not subtracting! */
1495 if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) {
1496 _mesa_error(ctx, GL_INVALID_VALUE,
1497 "glCopyTexSubImage%dD(yoffset+height)", dimensions);
1498 return GL_TRUE;
1499 }
1500 }
1501
1502 /* check z offset */
1503 if (dimensions > 2) {
1504 if (zoffset < -((GLint)teximage->Border)) {
1505 _mesa_error(ctx, GL_INVALID_VALUE,
1506 "glCopyTexSubImage%dD(zoffset)", dimensions);
1507 return GL_TRUE;
1508 }
1509 if (zoffset > (GLint) (teximage->Depth + teximage->Border)) {
1510 _mesa_error(ctx, GL_INVALID_VALUE,
1511 "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
1512 return GL_TRUE;
1513 }
1514 }
1515
1516 if (teximage->InternalFormat == GL_YCBCR_MESA) {
1517 _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D");
1518 return GL_TRUE;
1519 }
1520
1521 if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
1522 _mesa_error(ctx, GL_INVALID_OPERATION,
1523 "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)",
1524 dimensions, teximage->_BaseFormat);
1525 return GL_TRUE;
1526 }
1527
1528 /* From the EXT_texture_integer spec:
1529 *
1530 * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage*
1531 * if the texture internalformat is an integer format and the read color
1532 * buffer is not an integer format, or if the internalformat is not an
1533 * integer format and the read color buffer is an integer format."
1534 */
1535 if (_mesa_is_color_format(teximage->InternalFormat)) {
1536 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1537
1538 if (_mesa_is_format_integer_color(rb->Format) !=
1539 _mesa_is_format_integer_color(teximage->TexFormat)) {
1540 _mesa_error(ctx, GL_INVALID_OPERATION,
1541 "glCopyTexImage%dD(integer vs non-integer)", dimensions);
1542 return GL_TRUE;
1543 }
1544 }
1545
1546 /* if we get here, the parameters are OK */
1547 return GL_FALSE;
1548 }
1549
1550
1551 /** Callback info for walking over FBO hash table */
1552 struct cb_info
1553 {
1554 struct gl_context *ctx;
1555 struct gl_texture_object *texObj;
1556 GLuint level, face;
1557 };
1558
1559 /** Debug helper: override the user-requested internal format */
1560 static GLenum
1561 override_internal_format(GLenum internalFormat, GLint width, GLint height)
1562 {
1563 #if 0
1564 if (internalFormat == GL_RGBA16F_ARB ||
1565 internalFormat == GL_RGBA32F_ARB) {
1566 printf("Convert rgba float tex to int %d x %d\n", width, height);
1567 return GL_RGBA;
1568 }
1569 else if (internalFormat == GL_RGB16F_ARB ||
1570 internalFormat == GL_RGB32F_ARB) {
1571 printf("Convert rgb float tex to int %d x %d\n", width, height);
1572 return GL_RGB;
1573 }
1574 else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB ||
1575 internalFormat == GL_LUMINANCE_ALPHA32F_ARB) {
1576 printf("Convert luminance float tex to int %d x %d\n", width, height);
1577 return GL_LUMINANCE_ALPHA;
1578 }
1579 else if (internalFormat == GL_LUMINANCE16F_ARB ||
1580 internalFormat == GL_LUMINANCE32F_ARB) {
1581 printf("Convert luminance float tex to int %d x %d\n", width, height);
1582 return GL_LUMINANCE;
1583 }
1584 else if (internalFormat == GL_ALPHA16F_ARB ||
1585 internalFormat == GL_ALPHA32F_ARB) {
1586 printf("Convert luminance float tex to int %d x %d\n", width, height);
1587 return GL_ALPHA;
1588 }
1589 else {
1590 return internalFormat;
1591 }
1592 #else
1593 return internalFormat;
1594 #endif
1595 }
1596
1597
1598 /**
1599 * Choose the actual hardware format for a texture image.
1600 * Try to use the same format as the previous image level when possible.
1601 * Otherwise, ask the driver for the best format.
1602 * It's important to try to choose a consistant format for all levels
1603 * for efficient texture memory layout/allocation. In particular, this
1604 * comes up during automatic mipmap generation.
1605 */
1606 gl_format
1607 _mesa_choose_texture_format(struct gl_context *ctx,
1608 struct gl_texture_object *texObj,
1609 GLenum target, GLint level,
1610 GLenum internalFormat, GLenum format, GLenum type)
1611 {
1612 gl_format f;
1613
1614 /* see if we've already chosen a format for the previous level */
1615 if (level > 0) {
1616 struct gl_texture_image *prevImage =
1617 _mesa_select_tex_image(ctx, texObj, target, level - 1);
1618 /* See if the prev level is defined and has an internal format which
1619 * matches the new internal format.
1620 */
1621 if (prevImage &&
1622 prevImage->Width > 0 &&
1623 prevImage->InternalFormat == internalFormat) {
1624 /* use the same format */
1625 ASSERT(prevImage->TexFormat != MESA_FORMAT_NONE);
1626 return prevImage->TexFormat;
1627 }
1628 }
1629
1630 /* choose format from scratch */
1631 f = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
1632 ASSERT(f != MESA_FORMAT_NONE);
1633 return f;
1634 }
1635
1636 /**
1637 * Adjust pixel unpack params and image dimensions to strip off the
1638 * texture border.
1639 *
1640 * Gallium and intel don't support texture borders. They've seldem been used
1641 * and seldom been implemented correctly anyway.
1642 *
1643 * \param unpackNew returns the new pixel unpack parameters
1644 */
1645 static void
1646 strip_texture_border(GLint *border,
1647 GLint *width, GLint *height, GLint *depth,
1648 const struct gl_pixelstore_attrib *unpack,
1649 struct gl_pixelstore_attrib *unpackNew)
1650 {
1651 assert(*border > 0); /* sanity check */
1652
1653 *unpackNew = *unpack;
1654
1655 if (unpackNew->RowLength == 0)
1656 unpackNew->RowLength = *width;
1657
1658 if (depth && unpackNew->ImageHeight == 0)
1659 unpackNew->ImageHeight = *height;
1660
1661 unpackNew->SkipPixels += *border;
1662 if (height)
1663 unpackNew->SkipRows += *border;
1664 if (depth)
1665 unpackNew->SkipImages += *border;
1666
1667 assert(*width >= 3);
1668 *width = *width - 2 * *border;
1669 if (height && *height >= 3)
1670 *height = *height - 2 * *border;
1671 if (depth && *depth >= 3)
1672 *depth = *depth - 2 * *border;
1673 *border = 0;
1674 }
1675
1676 /**
1677 * Common code to implement all the glTexImage1D/2D/3D functions.
1678 */
1679 static void
1680 teximage(struct gl_context *ctx, GLuint dims,
1681 GLenum target, GLint level, GLint internalFormat,
1682 GLsizei width, GLsizei height, GLsizei depth,
1683 GLint border, GLenum format, GLenum type,
1684 const GLvoid *pixels)
1685 {
1686 GLboolean error;
1687 struct gl_pixelstore_attrib unpack_no_border;
1688 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
1689
1690 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1691
1692 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1693 _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
1694 dims,
1695 _mesa_lookup_enum_by_nr(target), level,
1696 _mesa_lookup_enum_by_nr(internalFormat),
1697 width, height, depth, border,
1698 _mesa_lookup_enum_by_nr(format),
1699 _mesa_lookup_enum_by_nr(type), pixels);
1700
1701 internalFormat = override_internal_format(internalFormat, width, height);
1702
1703 /* target error checking */
1704 if (!legal_teximage_target(ctx, dims, target)) {
1705 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)",
1706 dims, _mesa_lookup_enum_by_nr(target));
1707 return;
1708 }
1709
1710 /* general error checking */
1711 error = texture_error_check(ctx, dims, target, level, internalFormat,
1712 format, type, width, height, depth, border);
1713
1714 if (_mesa_is_proxy_texture(target)) {
1715 /* Proxy texture: just clear or set state depending on error checking */
1716 struct gl_texture_image *texImage =
1717 _mesa_get_proxy_tex_image(ctx, target, level);
1718
1719 if (error) {
1720 /* when error, clear all proxy texture image parameters */
1721 if (texImage)
1722 clear_teximage_fields(texImage);
1723 }
1724 else {
1725 /* no error, set the tex image parameters */
1726 struct gl_texture_object *texObj =
1727 _mesa_select_tex_object(ctx, target);
1728 gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
1729 target, level,
1730 internalFormat,
1731 format, type);
1732
1733 if (legal_texture_size(ctx, texFormat, width, height, depth)) {
1734 _mesa_init_teximage_fields(ctx, texImage, width, height,
1735 depth, border, internalFormat,
1736 texFormat);
1737 }
1738 else if (texImage) {
1739 clear_teximage_fields(texImage);
1740 }
1741 }
1742 }
1743 else {
1744 /* non-proxy target */
1745 struct gl_texture_object *texObj;
1746 struct gl_texture_image *texImage;
1747
1748 if (error) {
1749 return; /* error was recorded */
1750 }
1751
1752 /* Allow a hardware driver to just strip out the border, to provide
1753 * reliable but slightly incorrect hardware rendering instead of
1754 * rarely-tested software fallback rendering.
1755 */
1756 if (border && ctx->Const.StripTextureBorder) {
1757 strip_texture_border(&border, &width, &height, &depth, unpack,
1758 &unpack_no_border);
1759 unpack = &unpack_no_border;
1760 }
1761
1762 if (ctx->NewState & _NEW_PIXEL)
1763 _mesa_update_state(ctx);
1764
1765 texObj = _mesa_select_tex_object(ctx, target);
1766
1767 _mesa_lock_texture(ctx, texObj);
1768 {
1769 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
1770
1771 if (!texImage) {
1772 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
1773 }
1774 else {
1775 gl_format texFormat;
1776
1777 ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
1778
1779 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
1780 internalFormat, format,
1781 type);
1782
1783 if (legal_texture_size(ctx, texFormat, width, height, depth)) {
1784 _mesa_init_teximage_fields(ctx, texImage,
1785 width, height, depth,
1786 border, internalFormat, texFormat);
1787
1788 /* Give the texture to the driver. <pixels> may be null. */
1789 ASSERT(ctx->Driver.TexImage3D);
1790 switch (dims) {
1791 case 1:
1792 ctx->Driver.TexImage1D(ctx, texImage, internalFormat,
1793 width, border, format,
1794 type, pixels, unpack);
1795 break;
1796 case 2:
1797 ctx->Driver.TexImage2D(ctx, texImage, internalFormat,
1798 width, height, border, format,
1799 type, pixels, unpack);
1800 break;
1801 case 3:
1802 ctx->Driver.TexImage3D(ctx, texImage, internalFormat,
1803 width, height, depth, border, format,
1804 type, pixels, unpack);
1805 break;
1806 default:
1807 _mesa_problem(ctx, "invalid dims=%u in teximage()", dims);
1808 }
1809
1810 /* state update */
1811 texObj->_Complete = GL_FALSE;
1812 ctx->NewState |= _NEW_TEXTURE;
1813 }
1814 else {
1815 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
1816 }
1817 }
1818 }
1819 _mesa_unlock_texture(ctx, texObj);
1820 }
1821 }
1822
1823
1824 /*
1825 * Called from the API. Note that width includes the border.
1826 */
1827 void GLAPIENTRY
1828 _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
1829 GLsizei width, GLint border, GLenum format,
1830 GLenum type, const GLvoid *pixels )
1831 {
1832 GET_CURRENT_CONTEXT(ctx);
1833 teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
1834 border, format, type, pixels);
1835 }
1836
1837
1838 void GLAPIENTRY
1839 _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
1840 GLsizei width, GLsizei height, GLint border,
1841 GLenum format, GLenum type,
1842 const GLvoid *pixels )
1843 {
1844 GET_CURRENT_CONTEXT(ctx);
1845 teximage(ctx, 2, target, level, internalFormat, width, height, 1,
1846 border, format, type, pixels);
1847 }
1848
1849
1850 /*
1851 * Called by the API or display list executor.
1852 * Note that width and height include the border.
1853 */
1854 void GLAPIENTRY
1855 _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
1856 GLsizei width, GLsizei height, GLsizei depth,
1857 GLint border, GLenum format, GLenum type,
1858 const GLvoid *pixels )
1859 {
1860 GET_CURRENT_CONTEXT(ctx);
1861 teximage(ctx, 3, target, level, internalFormat, width, height, depth,
1862 border, format, type, pixels);
1863 }
1864
1865
1866 void GLAPIENTRY
1867 _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
1868 GLsizei width, GLsizei height, GLsizei depth,
1869 GLint border, GLenum format, GLenum type,
1870 const GLvoid *pixels )
1871 {
1872 _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
1873 depth, border, format, type, pixels);
1874 }
1875
1876
1877 /**
1878 * Implement all the glTexSubImage1/2/3D() functions.
1879 */
1880 static void
1881 texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
1882 GLint xoffset, GLint yoffset, GLint zoffset,
1883 GLsizei width, GLsizei height, GLsizei depth,
1884 GLenum format, GLenum type, const GLvoid *pixels )
1885 {
1886 struct gl_texture_object *texObj;
1887 struct gl_texture_image *texImage;
1888
1889 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1890
1891 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1892 _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
1893 dims,
1894 _mesa_lookup_enum_by_nr(target), level,
1895 xoffset, yoffset, zoffset, width, height, depth,
1896 _mesa_lookup_enum_by_nr(format),
1897 _mesa_lookup_enum_by_nr(type), pixels);
1898
1899 /* check target (proxies not allowed) */
1900 if (!legal_texsubimage_target(ctx, dims, target)) {
1901 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
1902 dims, _mesa_lookup_enum_by_nr(target));
1903 return;
1904 }
1905
1906 if (ctx->NewState & _NEW_PIXEL)
1907 _mesa_update_state(ctx);
1908
1909 if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset,
1910 width, height, depth, format, type)) {
1911 return; /* error was detected */
1912 }
1913
1914 texObj = _mesa_select_tex_object(ctx, target);
1915
1916 _mesa_lock_texture(ctx, texObj);
1917 {
1918 texImage = _mesa_select_tex_image(ctx, texObj, target, level);
1919
1920 if (subtexture_error_check2(ctx, dims, target, level,
1921 xoffset, yoffset, zoffset,
1922 width, height, depth,
1923 format, type, texImage)) {
1924 /* error was recorded */
1925 }
1926 else if (width > 0 && height > 0 && depth > 0) {
1927 /* If we have a border, offset=-1 is legal. Bias by border width. */
1928 switch (dims) {
1929 case 3:
1930 zoffset += texImage->Border;
1931 /* fall-through */
1932 case 2:
1933 yoffset += texImage->Border;
1934 /* fall-through */
1935 case 1:
1936 xoffset += texImage->Border;
1937 }
1938
1939 switch (dims) {
1940 case 1:
1941 ctx->Driver.TexSubImage1D(ctx, texImage,
1942 xoffset, width,
1943 format, type, pixels, &ctx->Unpack);
1944 break;
1945 case 2:
1946 ctx->Driver.TexSubImage2D(ctx, texImage,
1947 xoffset, yoffset, width, height,
1948 format, type, pixels, &ctx->Unpack);
1949 break;
1950 case 3:
1951 ctx->Driver.TexSubImage3D(ctx, texImage,
1952 xoffset, yoffset, zoffset,
1953 width, height, depth,
1954 format, type, pixels, &ctx->Unpack);
1955 break;
1956 default:
1957 _mesa_problem(ctx, "unexpected dims in subteximage()");
1958 }
1959
1960 ctx->NewState |= _NEW_TEXTURE;
1961 }
1962 }
1963 _mesa_unlock_texture(ctx, texObj);
1964 }
1965
1966
1967 void GLAPIENTRY
1968 _mesa_TexSubImage1D( GLenum target, GLint level,
1969 GLint xoffset, GLsizei width,
1970 GLenum format, GLenum type,
1971 const GLvoid *pixels )
1972 {
1973 GET_CURRENT_CONTEXT(ctx);
1974 texsubimage(ctx, 1, target, level,
1975 xoffset, 0, 0,
1976 width, 1, 1,
1977 format, type, pixels);
1978 }
1979
1980
1981 void GLAPIENTRY
1982 _mesa_TexSubImage2D( GLenum target, GLint level,
1983 GLint xoffset, GLint yoffset,
1984 GLsizei width, GLsizei height,
1985 GLenum format, GLenum type,
1986 const GLvoid *pixels )
1987 {
1988 GET_CURRENT_CONTEXT(ctx);
1989 texsubimage(ctx, 2, target, level,
1990 xoffset, yoffset, 0,
1991 width, height, 1,
1992 format, type, pixels);
1993 }
1994
1995
1996
1997 void GLAPIENTRY
1998 _mesa_TexSubImage3D( GLenum target, GLint level,
1999 GLint xoffset, GLint yoffset, GLint zoffset,
2000 GLsizei width, GLsizei height, GLsizei depth,
2001 GLenum format, GLenum type,
2002 const GLvoid *pixels )
2003 {
2004 GET_CURRENT_CONTEXT(ctx);
2005 texsubimage(ctx, 3, target, level,
2006 xoffset, yoffset, zoffset,
2007 width, height, depth,
2008 format, type, pixels);
2009 }
2010
2011
2012
2013 /**
2014 * For glCopyTexSubImage, return the source renderbuffer to copy texel data
2015 * from. This depends on whether the texture contains color or depth values.
2016 */
2017 static struct gl_renderbuffer *
2018 get_copy_tex_image_source(struct gl_context *ctx, gl_format texFormat)
2019 {
2020 if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) {
2021 /* reading from depth/stencil buffer */
2022 return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
2023 }
2024 else {
2025 /* copying from color buffer */
2026 return ctx->ReadBuffer->_ColorReadBuffer;
2027 }
2028 }
2029
2030
2031
2032 /**
2033 * Implement the glCopyTexImage1/2D() functions.
2034 */
2035 static void
2036 copyteximage(struct gl_context *ctx, GLuint dims,
2037 GLenum target, GLint level, GLenum internalFormat,
2038 GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
2039 {
2040 struct gl_texture_object *texObj;
2041 struct gl_texture_image *texImage;
2042
2043 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2044
2045 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2046 _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
2047 dims,
2048 _mesa_lookup_enum_by_nr(target), level,
2049 _mesa_lookup_enum_by_nr(internalFormat),
2050 x, y, width, height, border);
2051
2052 if (ctx->NewState & NEW_COPY_TEX_STATE)
2053 _mesa_update_state(ctx);
2054
2055 if (copytexture_error_check(ctx, dims, target, level, internalFormat,
2056 width, height, border))
2057 return;
2058
2059 texObj = _mesa_select_tex_object(ctx, target);
2060
2061 if (border && ctx->Const.StripTextureBorder) {
2062 x += border;
2063 width -= border * 2;
2064 if (dims == 2) {
2065 y += border;
2066 height -= border * 2;
2067 }
2068 border = 0;
2069 }
2070
2071 _mesa_lock_texture(ctx, texObj);
2072 {
2073 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
2074
2075 if (!texImage) {
2076 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
2077 }
2078 else {
2079 /* choose actual hw format */
2080 gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
2081 target, level,
2082 internalFormat,
2083 GL_NONE, GL_NONE);
2084
2085 if (legal_texture_size(ctx, texFormat, width, height, 1)) {
2086 GLint srcX = x, srcY = y, dstX = 0, dstY = 0;
2087
2088 /* Free old texture image */
2089 ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
2090
2091 _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
2092 border, internalFormat, texFormat);
2093
2094 /* Allocate texture memory (no pixel data yet) */
2095 if (dims == 1) {
2096 ctx->Driver.TexImage1D(ctx, texImage, internalFormat,
2097 width, border, GL_NONE, GL_NONE, NULL,
2098 &ctx->Unpack);
2099 }
2100 else {
2101 ctx->Driver.TexImage2D(ctx, texImage, internalFormat,
2102 width, height, border, GL_NONE, GL_NONE,
2103 NULL, &ctx->Unpack);
2104 }
2105
2106 if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
2107 &width, &height)) {
2108 struct gl_renderbuffer *srcRb =
2109 get_copy_tex_image_source(ctx, texImage->TexFormat);
2110
2111 if (dims == 1)
2112 ctx->Driver.CopyTexSubImage1D(ctx, texImage, dstX,
2113 srcRb, srcX, srcY, width);
2114
2115 else
2116 ctx->Driver.CopyTexSubImage2D(ctx, texImage, dstX, dstY,
2117 srcRb, srcX, srcY, width, height);
2118 }
2119
2120 /* state update */
2121 texObj->_Complete = GL_FALSE;
2122 ctx->NewState |= _NEW_TEXTURE;
2123 }
2124 else {
2125 /* probably too large of image */
2126 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
2127 }
2128 }
2129 }
2130 _mesa_unlock_texture(ctx, texObj);
2131 }
2132
2133
2134
2135 void GLAPIENTRY
2136 _mesa_CopyTexImage1D( GLenum target, GLint level,
2137 GLenum internalFormat,
2138 GLint x, GLint y,
2139 GLsizei width, GLint border )
2140 {
2141 GET_CURRENT_CONTEXT(ctx);
2142 copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border);
2143 }
2144
2145
2146
2147 void GLAPIENTRY
2148 _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
2149 GLint x, GLint y, GLsizei width, GLsizei height,
2150 GLint border )
2151 {
2152 GET_CURRENT_CONTEXT(ctx);
2153 copyteximage(ctx, 2, target, level, internalFormat,
2154 x, y, width, height, border);
2155 }
2156
2157
2158
2159 /**
2160 * Implementation for glCopyTexSubImage1/2/3D() functions.
2161 */
2162 static void
2163 copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
2164 GLint xoffset, GLint yoffset, GLint zoffset,
2165 GLint x, GLint y, GLsizei width, GLsizei height)
2166 {
2167 struct gl_texture_object *texObj;
2168 struct gl_texture_image *texImage;
2169
2170 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2171
2172 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2173 _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n",
2174 dims,
2175 _mesa_lookup_enum_by_nr(target),
2176 level, xoffset, yoffset, zoffset, x, y, width, height);
2177
2178 if (ctx->NewState & NEW_COPY_TEX_STATE)
2179 _mesa_update_state(ctx);
2180
2181 if (copytexsubimage_error_check1(ctx, dims, target, level))
2182 return;
2183
2184 texObj = _mesa_select_tex_object(ctx, target);
2185
2186 _mesa_lock_texture(ctx, texObj);
2187 {
2188 texImage = _mesa_select_tex_image(ctx, texObj, target, level);
2189
2190 if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset,
2191 zoffset, width, height, texImage)) {
2192 /* error was recored */
2193 }
2194 else {
2195 /* If we have a border, offset=-1 is legal. Bias by border width. */
2196 switch (dims) {
2197 case 3:
2198 zoffset += texImage->Border;
2199 /* fall-through */
2200 case 2:
2201 yoffset += texImage->Border;
2202 /* fall-through */
2203 case 1:
2204 xoffset += texImage->Border;
2205 }
2206
2207 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
2208 &width, &height)) {
2209 struct gl_renderbuffer *srcRb =
2210 get_copy_tex_image_source(ctx, texImage->TexFormat);
2211
2212 switch (dims) {
2213 case 1:
2214 ctx->Driver.CopyTexSubImage1D(ctx, texImage, xoffset,
2215 srcRb, x, y, width);
2216 break;
2217 case 2:
2218 ctx->Driver.CopyTexSubImage2D(ctx, texImage, xoffset, yoffset,
2219 srcRb, x, y, width, height);
2220 break;
2221 case 3:
2222 ctx->Driver.CopyTexSubImage3D(ctx, texImage,
2223 xoffset, yoffset, zoffset,
2224 srcRb, x, y, width, height);
2225 break;
2226 default:
2227 _mesa_problem(ctx, "bad dims in copytexsubimage()");
2228 }
2229
2230 ctx->NewState |= _NEW_TEXTURE;
2231 }
2232 }
2233 }
2234 _mesa_unlock_texture(ctx, texObj);
2235 }
2236
2237
2238 void GLAPIENTRY
2239 _mesa_CopyTexSubImage1D( GLenum target, GLint level,
2240 GLint xoffset, GLint x, GLint y, GLsizei width )
2241 {
2242 GET_CURRENT_CONTEXT(ctx);
2243 copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1);
2244 }
2245
2246
2247
2248 void GLAPIENTRY
2249 _mesa_CopyTexSubImage2D( GLenum target, GLint level,
2250 GLint xoffset, GLint yoffset,
2251 GLint x, GLint y, GLsizei width, GLsizei height )
2252 {
2253 GET_CURRENT_CONTEXT(ctx);
2254 copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y,
2255 width, height);
2256 }
2257
2258
2259
2260 void GLAPIENTRY
2261 _mesa_CopyTexSubImage3D( GLenum target, GLint level,
2262 GLint xoffset, GLint yoffset, GLint zoffset,
2263 GLint x, GLint y, GLsizei width, GLsizei height )
2264 {
2265 GET_CURRENT_CONTEXT(ctx);
2266 copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
2267 x, y, width, height);
2268 }