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