1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.5
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (c) 2008-2009 VMware, Inc.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /*
27 * Authors:
28 * Brian Paul
29 */
30
31 /**
32 * The GL texture image functions in teximage.c basically just do
33 * error checking and data structure allocation. They in turn call
34 * device driver functions which actually copy/convert/store the user's
35 * texture image data.
36 *
37 * However, most device drivers will be able to use the fallback functions
38 * in this file. That is, most drivers will have the following bit of
39 * code:
40 * ctx->Driver.TexImage = _mesa_store_teximage;
41 * ctx->Driver.TexSubImage = _mesa_store_texsubimage;
42 * etc...
43 *
44 * Texture image processing is actually kind of complicated. We have to do:
45 * Format/type conversions
46 * pixel unpacking
47 * pixel transfer (scale, bais, lookup, etc)
48 *
49 * These functions can handle most everything, including processing full
50 * images and sub-images.
51 */
52
53
54 #include "glheader.h"
55 #include "bufferobj.h"
56 #include "colormac.h"
57 #include "format_pack.h"
58 #include "image.h"
59 #include "macros.h"
60 #include "mipmap.h"
61 #include "mfeatures.h"
62 #include "mtypes.h"
63 #include "pack.h"
64 #include "pbo.h"
65 #include "imports.h"
66 #include "texcompress.h"
67 #include "texcompress_fxt1.h"
68 #include "texcompress_rgtc.h"
69 #include "texcompress_s3tc.h"
70 #include "texcompress_etc.h"
71 #include "teximage.h"
72 #include "texstore.h"
73 #include "enums.h"
74 #include "glformats.h"
75 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
76 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
77
78
79 enum {
80 ZERO = 4,
81 ONE = 5
82 };
83
84
85 /**
86 * Texture image storage function.
87 */
88 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
89
90
91 /**
92 * Return GL_TRUE if the given image format is one that be converted
93 * to another format by swizzling.
94 */
95 static GLboolean
can_swizzle(GLenum logicalBaseFormat)96 can_swizzle(GLenum logicalBaseFormat)
97 {
98 switch (logicalBaseFormat) {
99 case GL_RGBA:
100 case GL_RGB:
101 case GL_LUMINANCE_ALPHA:
102 case GL_INTENSITY:
103 case GL_ALPHA:
104 case GL_LUMINANCE:
105 case GL_RED:
106 case GL_GREEN:
107 case GL_BLUE:
108 case GL_BGR:
109 case GL_BGRA:
110 case GL_ABGR_EXT:
111 case GL_RG:
112 return GL_TRUE;
113 default:
114 return GL_FALSE;
115 }
116 }
117
118
119
120 enum {
121 IDX_LUMINANCE = 0,
122 IDX_ALPHA,
123 IDX_INTENSITY,
124 IDX_LUMINANCE_ALPHA,
125 IDX_RGB,
126 IDX_RGBA,
127 IDX_RED,
128 IDX_GREEN,
129 IDX_BLUE,
130 IDX_BGR,
131 IDX_BGRA,
132 IDX_ABGR,
133 IDX_RG,
134 MAX_IDX
135 };
136
137 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
138 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
139 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
140 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
141
142
143 static const struct {
144 GLubyte format_idx;
145 GLubyte to_rgba[6];
146 GLubyte from_rgba[6];
147 } mappings[MAX_IDX] =
148 {
149 {
150 IDX_LUMINANCE,
151 MAP4(0,0,0,ONE),
152 MAP1(0)
153 },
154
155 {
156 IDX_ALPHA,
157 MAP4(ZERO, ZERO, ZERO, 0),
158 MAP1(3)
159 },
160
161 {
162 IDX_INTENSITY,
163 MAP4(0, 0, 0, 0),
164 MAP1(0),
165 },
166
167 {
168 IDX_LUMINANCE_ALPHA,
169 MAP4(0,0,0,1),
170 MAP2(0,3)
171 },
172
173 {
174 IDX_RGB,
175 MAP4(0,1,2,ONE),
176 MAP3(0,1,2)
177 },
178
179 {
180 IDX_RGBA,
181 MAP4(0,1,2,3),
182 MAP4(0,1,2,3),
183 },
184
185 {
186 IDX_RED,
187 MAP4(0, ZERO, ZERO, ONE),
188 MAP1(0),
189 },
190
191 {
192 IDX_GREEN,
193 MAP4(ZERO, 0, ZERO, ONE),
194 MAP1(1),
195 },
196
197 {
198 IDX_BLUE,
199 MAP4(ZERO, ZERO, 0, ONE),
200 MAP1(2),
201 },
202
203 {
204 IDX_BGR,
205 MAP4(2,1,0,ONE),
206 MAP3(2,1,0)
207 },
208
209 {
210 IDX_BGRA,
211 MAP4(2,1,0,3),
212 MAP4(2,1,0,3)
213 },
214
215 {
216 IDX_ABGR,
217 MAP4(3,2,1,0),
218 MAP4(3,2,1,0)
219 },
220
221 {
222 IDX_RG,
223 MAP4(0, 1, ZERO, ONE),
224 MAP2(0, 1)
225 },
226 };
227
228
229
230 /**
231 * Convert a GL image format enum to an IDX_* value (see above).
232 */
233 static int
get_map_idx(GLenum value)234 get_map_idx(GLenum value)
235 {
236 switch (value) {
237 case GL_LUMINANCE: return IDX_LUMINANCE;
238 case GL_ALPHA: return IDX_ALPHA;
239 case GL_INTENSITY: return IDX_INTENSITY;
240 case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
241 case GL_RGB: return IDX_RGB;
242 case GL_RGBA: return IDX_RGBA;
243 case GL_RED: return IDX_RED;
244 case GL_GREEN: return IDX_GREEN;
245 case GL_BLUE: return IDX_BLUE;
246 case GL_BGR: return IDX_BGR;
247 case GL_BGRA: return IDX_BGRA;
248 case GL_ABGR_EXT: return IDX_ABGR;
249 case GL_RG: return IDX_RG;
250 default:
251 _mesa_problem(NULL, "Unexpected inFormat");
252 return 0;
253 }
254 }
255
256
257 /**
258 * When promoting texture formats (see below) we need to compute the
259 * mapping of dest components back to source components.
260 * This function does that.
261 * \param inFormat the incoming format of the texture
262 * \param outFormat the final texture format
263 * \return map[6] a full 6-component map
264 */
265 static void
compute_component_mapping(GLenum inFormat,GLenum outFormat,GLubyte * map)266 compute_component_mapping(GLenum inFormat, GLenum outFormat,
267 GLubyte *map)
268 {
269 const int inFmt = get_map_idx(inFormat);
270 const int outFmt = get_map_idx(outFormat);
271 const GLubyte *in2rgba = mappings[inFmt].to_rgba;
272 const GLubyte *rgba2out = mappings[outFmt].from_rgba;
273 int i;
274
275 for (i = 0; i < 4; i++)
276 map[i] = in2rgba[rgba2out[i]];
277
278 map[ZERO] = ZERO;
279 map[ONE] = ONE;
280
281 #if 0
282 printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
283 inFormat, _mesa_lookup_enum_by_nr(inFormat),
284 outFormat, _mesa_lookup_enum_by_nr(outFormat),
285 map[0],
286 map[1],
287 map[2],
288 map[3],
289 map[4],
290 map[5]);
291 #endif
292 }
293
294
295 /**
296 * Make a temporary (color) texture image with GLfloat components.
297 * Apply all needed pixel unpacking and pixel transfer operations.
298 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
299 * Suppose the user specifies GL_LUMINANCE as the internal texture format
300 * but the graphics hardware doesn't support luminance textures. So, we might
301 * use an RGB hardware format instead.
302 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
303 *
304 * \param ctx the rendering context
305 * \param dims image dimensions: 1, 2 or 3
306 * \param logicalBaseFormat basic texture derived from the user's
307 * internal texture format value
308 * \param textureBaseFormat the actual basic format of the texture
309 * \param srcWidth source image width
310 * \param srcHeight source image height
311 * \param srcDepth source image depth
312 * \param srcFormat source image format
313 * \param srcType source image type
314 * \param srcAddr source image address
315 * \param srcPacking source image pixel packing
316 * \return resulting image with format = textureBaseFormat and type = GLfloat.
317 */
318 GLfloat *
_mesa_make_temp_float_image(struct gl_context * ctx,GLuint dims,GLenum logicalBaseFormat,GLenum textureBaseFormat,GLint srcWidth,GLint srcHeight,GLint srcDepth,GLenum srcFormat,GLenum srcType,const GLvoid * srcAddr,const struct gl_pixelstore_attrib * srcPacking,GLbitfield transferOps)319 _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
320 GLenum logicalBaseFormat,
321 GLenum textureBaseFormat,
322 GLint srcWidth, GLint srcHeight, GLint srcDepth,
323 GLenum srcFormat, GLenum srcType,
324 const GLvoid *srcAddr,
325 const struct gl_pixelstore_attrib *srcPacking,
326 GLbitfield transferOps)
327 {
328 GLfloat *tempImage;
329 const GLint components = _mesa_components_in_format(logicalBaseFormat);
330 const GLint srcStride =
331 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
332 GLfloat *dst;
333 GLint img, row;
334
335 ASSERT(dims >= 1 && dims <= 3);
336
337 ASSERT(logicalBaseFormat == GL_RGBA ||
338 logicalBaseFormat == GL_RGB ||
339 logicalBaseFormat == GL_RG ||
340 logicalBaseFormat == GL_RED ||
341 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
342 logicalBaseFormat == GL_LUMINANCE ||
343 logicalBaseFormat == GL_ALPHA ||
344 logicalBaseFormat == GL_INTENSITY ||
345 logicalBaseFormat == GL_DEPTH_COMPONENT);
346
347 ASSERT(textureBaseFormat == GL_RGBA ||
348 textureBaseFormat == GL_RGB ||
349 textureBaseFormat == GL_RG ||
350 textureBaseFormat == GL_RED ||
351 textureBaseFormat == GL_LUMINANCE_ALPHA ||
352 textureBaseFormat == GL_LUMINANCE ||
353 textureBaseFormat == GL_ALPHA ||
354 textureBaseFormat == GL_INTENSITY ||
355 textureBaseFormat == GL_DEPTH_COMPONENT);
356
357 tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
358 * components * sizeof(GLfloat));
359 if (!tempImage)
360 return NULL;
361
362 dst = tempImage;
363 for (img = 0; img < srcDepth; img++) {
364 const GLubyte *src
365 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
366 srcWidth, srcHeight,
367 srcFormat, srcType,
368 img, 0, 0);
369 for (row = 0; row < srcHeight; row++) {
370 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
371 dst, srcFormat, srcType, src,
372 srcPacking, transferOps);
373 dst += srcWidth * components;
374 src += srcStride;
375 }
376 }
377
378 if (logicalBaseFormat != textureBaseFormat) {
379 /* more work */
380 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
381 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
382 GLfloat *newImage;
383 GLint i, n;
384 GLubyte map[6];
385
386 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
387 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
388 textureBaseFormat == GL_LUMINANCE_ALPHA);
389
390 /* The actual texture format should have at least as many components
391 * as the logical texture format.
392 */
393 ASSERT(texComponents >= logComponents);
394
395 newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
396 * texComponents * sizeof(GLfloat));
397 if (!newImage) {
398 free(tempImage);
399 return NULL;
400 }
401
402 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
403
404 n = srcWidth * srcHeight * srcDepth;
405 for (i = 0; i < n; i++) {
406 GLint k;
407 for (k = 0; k < texComponents; k++) {
408 GLint j = map[k];
409 if (j == ZERO)
410 newImage[i * texComponents + k] = 0.0F;
411 else if (j == ONE)
412 newImage[i * texComponents + k] = 1.0F;
413 else
414 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
415 }
416 }
417
418 free(tempImage);
419 tempImage = newImage;
420 }
421
422 return tempImage;
423 }
424
425
426 /**
427 * Make temporary image with uint pixel values. Used for unsigned
428 * integer-valued textures.
429 */
430 static GLuint *
make_temp_uint_image(struct gl_context * ctx,GLuint dims,GLenum logicalBaseFormat,GLenum textureBaseFormat,GLint srcWidth,GLint srcHeight,GLint srcDepth,GLenum srcFormat,GLenum srcType,const GLvoid * srcAddr,const struct gl_pixelstore_attrib * srcPacking)431 make_temp_uint_image(struct gl_context *ctx, GLuint dims,
432 GLenum logicalBaseFormat,
433 GLenum textureBaseFormat,
434 GLint srcWidth, GLint srcHeight, GLint srcDepth,
435 GLenum srcFormat, GLenum srcType,
436 const GLvoid *srcAddr,
437 const struct gl_pixelstore_attrib *srcPacking)
438 {
439 GLuint *tempImage;
440 const GLint components = _mesa_components_in_format(logicalBaseFormat);
441 const GLint srcStride =
442 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
443 GLuint *dst;
444 GLint img, row;
445
446 ASSERT(dims >= 1 && dims <= 3);
447
448 ASSERT(logicalBaseFormat == GL_RGBA ||
449 logicalBaseFormat == GL_RGB ||
450 logicalBaseFormat == GL_RG ||
451 logicalBaseFormat == GL_RED ||
452 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
453 logicalBaseFormat == GL_LUMINANCE ||
454 logicalBaseFormat == GL_INTENSITY ||
455 logicalBaseFormat == GL_ALPHA);
456
457 ASSERT(textureBaseFormat == GL_RGBA ||
458 textureBaseFormat == GL_RGB ||
459 textureBaseFormat == GL_RG ||
460 textureBaseFormat == GL_RED ||
461 textureBaseFormat == GL_LUMINANCE_ALPHA ||
462 textureBaseFormat == GL_LUMINANCE ||
463 textureBaseFormat == GL_INTENSITY ||
464 textureBaseFormat == GL_ALPHA);
465
466 tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
467 * components * sizeof(GLuint));
468 if (!tempImage)
469 return NULL;
470
471 dst = tempImage;
472 for (img = 0; img < srcDepth; img++) {
473 const GLubyte *src
474 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
475 srcWidth, srcHeight,
476 srcFormat, srcType,
477 img, 0, 0);
478 for (row = 0; row < srcHeight; row++) {
479 _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
480 dst, srcFormat, srcType, src,
481 srcPacking);
482 dst += srcWidth * components;
483 src += srcStride;
484 }
485 }
486
487 if (logicalBaseFormat != textureBaseFormat) {
488 /* more work */
489 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
490 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
491 GLuint *newImage;
492 GLint i, n;
493 GLubyte map[6];
494
495 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
496 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
497 textureBaseFormat == GL_LUMINANCE_ALPHA);
498
499 /* The actual texture format should have at least as many components
500 * as the logical texture format.
501 */
502 ASSERT(texComponents >= logComponents);
503
504 newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
505 * texComponents * sizeof(GLuint));
506 if (!newImage) {
507 free(tempImage);
508 return NULL;
509 }
510
511 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
512
513 n = srcWidth * srcHeight * srcDepth;
514 for (i = 0; i < n; i++) {
515 GLint k;
516 for (k = 0; k < texComponents; k++) {
517 GLint j = map[k];
518 if (j == ZERO)
519 newImage[i * texComponents + k] = 0;
520 else if (j == ONE)
521 newImage[i * texComponents + k] = 1;
522 else
523 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
524 }
525 }
526
527 free(tempImage);
528 tempImage = newImage;
529 }
530
531 return tempImage;
532 }
533
534
535
536 /**
537 * Make a temporary (color) texture image with GLubyte components.
538 * Apply all needed pixel unpacking and pixel transfer operations.
539 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
540 * Suppose the user specifies GL_LUMINANCE as the internal texture format
541 * but the graphics hardware doesn't support luminance textures. So, we might
542 * use an RGB hardware format instead.
543 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
544 *
545 * \param ctx the rendering context
546 * \param dims image dimensions: 1, 2 or 3
547 * \param logicalBaseFormat basic texture derived from the user's
548 * internal texture format value
549 * \param textureBaseFormat the actual basic format of the texture
550 * \param srcWidth source image width
551 * \param srcHeight source image height
552 * \param srcDepth source image depth
553 * \param srcFormat source image format
554 * \param srcType source image type
555 * \param srcAddr source image address
556 * \param srcPacking source image pixel packing
557 * \return resulting image with format = textureBaseFormat and type = GLubyte.
558 */
559 GLubyte *
_mesa_make_temp_ubyte_image(struct gl_context * ctx,GLuint dims,GLenum logicalBaseFormat,GLenum textureBaseFormat,GLint srcWidth,GLint srcHeight,GLint srcDepth,GLenum srcFormat,GLenum srcType,const GLvoid * srcAddr,const struct gl_pixelstore_attrib * srcPacking)560 _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
561 GLenum logicalBaseFormat,
562 GLenum textureBaseFormat,
563 GLint srcWidth, GLint srcHeight, GLint srcDepth,
564 GLenum srcFormat, GLenum srcType,
565 const GLvoid *srcAddr,
566 const struct gl_pixelstore_attrib *srcPacking)
567 {
568 GLuint transferOps = ctx->_ImageTransferState;
569 const GLint components = _mesa_components_in_format(logicalBaseFormat);
570 GLint img, row;
571 GLubyte *tempImage, *dst;
572
573 ASSERT(dims >= 1 && dims <= 3);
574
575 ASSERT(logicalBaseFormat == GL_RGBA ||
576 logicalBaseFormat == GL_RGB ||
577 logicalBaseFormat == GL_RG ||
578 logicalBaseFormat == GL_RED ||
579 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
580 logicalBaseFormat == GL_LUMINANCE ||
581 logicalBaseFormat == GL_ALPHA ||
582 logicalBaseFormat == GL_INTENSITY);
583
584 ASSERT(textureBaseFormat == GL_RGBA ||
585 textureBaseFormat == GL_RGB ||
586 textureBaseFormat == GL_RG ||
587 textureBaseFormat == GL_RED ||
588 textureBaseFormat == GL_LUMINANCE_ALPHA ||
589 textureBaseFormat == GL_LUMINANCE ||
590 textureBaseFormat == GL_ALPHA ||
591 textureBaseFormat == GL_INTENSITY);
592
593 /* unpack and transfer the source image */
594 tempImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
595 * components * sizeof(GLubyte));
596 if (!tempImage) {
597 return NULL;
598 }
599
600 dst = tempImage;
601 for (img = 0; img < srcDepth; img++) {
602 const GLint srcStride =
603 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
604 const GLubyte *src =
605 (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
606 srcWidth, srcHeight,
607 srcFormat, srcType,
608 img, 0, 0);
609 for (row = 0; row < srcHeight; row++) {
610 _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst,
611 srcFormat, srcType, src, srcPacking,
612 transferOps);
613 dst += srcWidth * components;
614 src += srcStride;
615 }
616 }
617
618 if (logicalBaseFormat != textureBaseFormat) {
619 /* one more conversion step */
620 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
621 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
622 GLubyte *newImage;
623 GLint i, n;
624 GLubyte map[6];
625
626 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
627 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
628 textureBaseFormat == GL_LUMINANCE_ALPHA);
629
630 /* The actual texture format should have at least as many components
631 * as the logical texture format.
632 */
633 ASSERT(texComponents >= logComponents);
634
635 newImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
636 * texComponents * sizeof(GLubyte));
637 if (!newImage) {
638 free(tempImage);
639 return NULL;
640 }
641
642 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
643
644 n = srcWidth * srcHeight * srcDepth;
645 for (i = 0; i < n; i++) {
646 GLint k;
647 for (k = 0; k < texComponents; k++) {
648 GLint j = map[k];
649 if (j == ZERO)
650 newImage[i * texComponents + k] = 0;
651 else if (j == ONE)
652 newImage[i * texComponents + k] = 255;
653 else
654 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
655 }
656 }
657
658 free(tempImage);
659 tempImage = newImage;
660 }
661
662 return tempImage;
663 }
664
665
666 /**
667 * Copy GLubyte pixels from <src> to <dst> with swizzling.
668 * \param dst destination pixels
669 * \param dstComponents number of color components in destination pixels
670 * \param src source pixels
671 * \param srcComponents number of color components in source pixels
672 * \param map the swizzle mapping. map[X] says where to find the X component
673 * in the source image's pixels. For example, if the source image
674 * is GL_BGRA and X = red, map[0] yields 2.
675 * \param count number of pixels to copy/swizzle.
676 */
677 static void
swizzle_copy(GLubyte * dst,GLuint dstComponents,const GLubyte * src,GLuint srcComponents,const GLubyte * map,GLuint count)678 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
679 GLuint srcComponents, const GLubyte *map, GLuint count)
680 {
681 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
682 do { \
683 GLuint i; \
684 for (i = 0; i < count; i++) { \
685 GLuint j; \
686 if (srcComps == 4) { \
687 COPY_4UBV(tmp, src); \
688 } \
689 else { \
690 for (j = 0; j < srcComps; j++) { \
691 tmp[j] = src[j]; \
692 } \
693 } \
694 src += srcComps; \
695 for (j = 0; j < dstComps; j++) { \
696 dst[j] = tmp[map[j]]; \
697 } \
698 dst += dstComps; \
699 } \
700 } while (0)
701
702 GLubyte tmp[6];
703
704 tmp[ZERO] = 0x0;
705 tmp[ONE] = 0xff;
706
707 ASSERT(srcComponents <= 4);
708 ASSERT(dstComponents <= 4);
709
710 switch (dstComponents) {
711 case 4:
712 switch (srcComponents) {
713 case 4:
714 SWZ_CPY(dst, src, count, 4, 4);
715 break;
716 case 3:
717 SWZ_CPY(dst, src, count, 4, 3);
718 break;
719 case 2:
720 SWZ_CPY(dst, src, count, 4, 2);
721 break;
722 case 1:
723 SWZ_CPY(dst, src, count, 4, 1);
724 break;
725 default:
726 ;
727 }
728 break;
729 case 3:
730 switch (srcComponents) {
731 case 4:
732 SWZ_CPY(dst, src, count, 3, 4);
733 break;
734 case 3:
735 SWZ_CPY(dst, src, count, 3, 3);
736 break;
737 case 2:
738 SWZ_CPY(dst, src, count, 3, 2);
739 break;
740 case 1:
741 SWZ_CPY(dst, src, count, 3, 1);
742 break;
743 default:
744 ;
745 }
746 break;
747 case 2:
748 switch (srcComponents) {
749 case 4:
750 SWZ_CPY(dst, src, count, 2, 4);
751 break;
752 case 3:
753 SWZ_CPY(dst, src, count, 2, 3);
754 break;
755 case 2:
756 SWZ_CPY(dst, src, count, 2, 2);
757 break;
758 case 1:
759 SWZ_CPY(dst, src, count, 2, 1);
760 break;
761 default:
762 ;
763 }
764 break;
765 case 1:
766 switch (srcComponents) {
767 case 4:
768 SWZ_CPY(dst, src, count, 1, 4);
769 break;
770 case 3:
771 SWZ_CPY(dst, src, count, 1, 3);
772 break;
773 case 2:
774 SWZ_CPY(dst, src, count, 1, 2);
775 break;
776 case 1:
777 SWZ_CPY(dst, src, count, 1, 1);
778 break;
779 default:
780 ;
781 }
782 break;
783 default:
784 ;
785 }
786 #undef SWZ_CPY
787 }
788
789
790
791 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
792 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
793
794
795 /**
796 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
797 * mapping array depending on endianness.
798 */
799 static const GLubyte *
type_mapping(GLenum srcType)800 type_mapping( GLenum srcType )
801 {
802 switch (srcType) {
803 case GL_BYTE:
804 case GL_UNSIGNED_BYTE:
805 return map_identity;
806 case GL_UNSIGNED_INT_8_8_8_8:
807 return _mesa_little_endian() ? map_3210 : map_identity;
808 case GL_UNSIGNED_INT_8_8_8_8_REV:
809 return _mesa_little_endian() ? map_identity : map_3210;
810 default:
811 return NULL;
812 }
813 }
814
815
816 /**
817 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
818 * mapping array depending on pixelstore byte swapping state.
819 */
820 static const GLubyte *
byteswap_mapping(GLboolean swapBytes,GLenum srcType)821 byteswap_mapping( GLboolean swapBytes,
822 GLenum srcType )
823 {
824 if (!swapBytes)
825 return map_identity;
826
827 switch (srcType) {
828 case GL_BYTE:
829 case GL_UNSIGNED_BYTE:
830 return map_identity;
831 case GL_UNSIGNED_INT_8_8_8_8:
832 case GL_UNSIGNED_INT_8_8_8_8_REV:
833 return map_3210;
834 default:
835 return NULL;
836 }
837 }
838
839
840
841 /**
842 * Transfer a GLubyte texture image with component swizzling.
843 */
844 static void
_mesa_swizzle_ubyte_image(struct gl_context * ctx,GLuint dimensions,GLenum srcFormat,GLenum srcType,GLenum baseInternalFormat,const GLubyte * rgba2dst,GLuint dstComponents,GLint dstRowStride,GLubyte ** dstSlices,GLint srcWidth,GLint srcHeight,GLint srcDepth,const GLvoid * srcAddr,const struct gl_pixelstore_attrib * srcPacking)845 _mesa_swizzle_ubyte_image(struct gl_context *ctx,
846 GLuint dimensions,
847 GLenum srcFormat,
848 GLenum srcType,
849
850 GLenum baseInternalFormat,
851
852 const GLubyte *rgba2dst,
853 GLuint dstComponents,
854
855 GLint dstRowStride,
856 GLubyte **dstSlices,
857
858 GLint srcWidth, GLint srcHeight, GLint srcDepth,
859 const GLvoid *srcAddr,
860 const struct gl_pixelstore_attrib *srcPacking )
861 {
862 GLint srcComponents = _mesa_components_in_format(srcFormat);
863 const GLubyte *srctype2ubyte, *swap;
864 GLubyte map[4], src2base[6], base2rgba[6];
865 GLint i;
866 const GLint srcRowStride =
867 _mesa_image_row_stride(srcPacking, srcWidth,
868 srcFormat, GL_UNSIGNED_BYTE);
869 const GLint srcImageStride
870 = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
871 GL_UNSIGNED_BYTE);
872 const GLubyte *srcImage
873 = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
874 srcWidth, srcHeight, srcFormat,
875 GL_UNSIGNED_BYTE, 0, 0, 0);
876
877 (void) ctx;
878
879 /* Translate from src->baseInternal->GL_RGBA->dst. This will
880 * correctly deal with RGBA->RGB->RGBA conversions where the final
881 * A value must be 0xff regardless of the incoming alpha values.
882 */
883 compute_component_mapping(srcFormat, baseInternalFormat, src2base);
884 compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
885 swap = byteswap_mapping(srcPacking->SwapBytes, srcType);
886 srctype2ubyte = type_mapping(srcType);
887
888
889 for (i = 0; i < 4; i++)
890 map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
891
892 /* printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
893
894 if (srcComponents == dstComponents &&
895 srcRowStride == dstRowStride &&
896 srcRowStride == srcWidth * srcComponents &&
897 dimensions < 3) {
898 /* 1 and 2D images only */
899 GLubyte *dstImage = dstSlices[0];
900 swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
901 srcWidth * srcHeight);
902 }
903 else {
904 GLint img, row;
905 for (img = 0; img < srcDepth; img++) {
906 const GLubyte *srcRow = srcImage;
907 GLubyte *dstRow = dstSlices[img];
908 for (row = 0; row < srcHeight; row++) {
909 swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
910 dstRow += dstRowStride;
911 srcRow += srcRowStride;
912 }
913 srcImage += srcImageStride;
914 }
915 }
916 }
917
918
919 /**
920 * Teximage storage routine for when a simple memcpy will do.
921 * No pixel transfer operations or special texel encodings allowed.
922 * 1D, 2D and 3D images supported.
923 */
924 static void
memcpy_texture(struct gl_context * ctx,GLuint dimensions,gl_format dstFormat,GLint dstRowStride,GLubyte ** dstSlices,GLint srcWidth,GLint srcHeight,GLint srcDepth,GLenum srcFormat,GLenum srcType,const GLvoid * srcAddr,const struct gl_pixelstore_attrib * srcPacking)925 memcpy_texture(struct gl_context *ctx,
926 GLuint dimensions,
927 gl_format dstFormat,
928 GLint dstRowStride,
929 GLubyte **dstSlices,
930 GLint srcWidth, GLint srcHeight, GLint srcDepth,
931 GLenum srcFormat, GLenum srcType,
932 const GLvoid *srcAddr,
933 const struct gl_pixelstore_attrib *srcPacking)
934 {
935 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
936 srcFormat, srcType);
937 const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
938 srcWidth, srcHeight, srcFormat, srcType);
939 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
940 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
941 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
942 const GLint bytesPerRow = srcWidth * texelBytes;
943
944 if (dstRowStride == srcRowStride &&
945 dstRowStride == bytesPerRow) {
946 /* memcpy image by image */
947 GLint img;
948 for (img = 0; img < srcDepth; img++) {
949 GLubyte *dstImage = dstSlices[img];
950 memcpy(dstImage, srcImage, bytesPerRow * srcHeight);
951 srcImage += srcImageStride;
952 }
953 }
954 else {
955 /* memcpy row by row */
956 GLint img, row;
957 for (img = 0; img < srcDepth; img++) {
958 const GLubyte *srcRow = srcImage;
959 GLubyte *dstRow = dstSlices[img];
960 for (row = 0; row < srcHeight; row++) {
961 memcpy(dstRow, srcRow, bytesPerRow);
962 dstRow += dstRowStride;
963 srcRow += srcRowStride;
964 }
965 srcImage += srcImageStride;
966 }
967 }
968 }
969
970
971 /**
972 * General-case function for storing a color texture images with
973 * components that can be represented with ubytes. Example destination
974 * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.
975 */
976 static GLboolean
store_ubyte_texture(TEXSTORE_PARAMS)977 store_ubyte_texture(TEXSTORE_PARAMS)
978 {
979 const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
980 GLubyte *tempImage, *src;
981 GLint img;
982
983 tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
984 baseInternalFormat,
985 GL_RGBA,
986 srcWidth, srcHeight, srcDepth,
987 srcFormat, srcType, srcAddr,
988 srcPacking);
989 if (!tempImage)
990 return GL_FALSE;
991
992 src = tempImage;
993 for (img = 0; img < srcDepth; img++) {
994 _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
995 src, srcRowStride,
996 dstSlices[img], dstRowStride);
997 src += srcHeight * srcRowStride;
998 }
999 free(tempImage);
1000
1001 return GL_TRUE;
1002 }
1003
1004
1005
1006
1007 /**
1008 * Store a 32-bit integer or float depth component texture image.
1009 */
1010 static GLboolean
_mesa_texstore_z32(TEXSTORE_PARAMS)1011 _mesa_texstore_z32(TEXSTORE_PARAMS)
1012 {
1013 const GLuint depthScale = 0xffffffff;
1014 GLenum dstType;
1015 (void) dims;
1016 ASSERT(dstFormat == MESA_FORMAT_Z32 ||
1017 dstFormat == MESA_FORMAT_Z32_FLOAT);
1018 ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
1019
1020 if (dstFormat == MESA_FORMAT_Z32)
1021 dstType = GL_UNSIGNED_INT;
1022 else
1023 dstType = GL_FLOAT;
1024
1025 if (ctx->Pixel.DepthScale == 1.0f &&
1026 ctx->Pixel.DepthBias == 0.0f &&
1027 !srcPacking->SwapBytes &&
1028 baseInternalFormat == GL_DEPTH_COMPONENT &&
1029 srcFormat == GL_DEPTH_COMPONENT &&
1030 srcType == dstType) {
1031 /* simple memcpy path */
1032 memcpy_texture(ctx, dims,
1033 dstFormat,
1034 dstRowStride, dstSlices,
1035 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1036 srcAddr, srcPacking);
1037 }
1038 else {
1039 /* general path */
1040 GLint img, row;
1041 for (img = 0; img < srcDepth; img++) {
1042 GLubyte *dstRow = dstSlices[img];
1043 for (row = 0; row < srcHeight; row++) {
1044 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1045 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1046 _mesa_unpack_depth_span(ctx, srcWidth,
1047 dstType, dstRow,
1048 depthScale, srcType, src, srcPacking);
1049 dstRow += dstRowStride;
1050 }
1051 }
1052 }
1053 return GL_TRUE;
1054 }
1055
1056
1057 /**
1058 * Store a 24-bit integer depth component texture image.
1059 */
1060 static GLboolean
_mesa_texstore_x8_z24(TEXSTORE_PARAMS)1061 _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
1062 {
1063 const GLuint depthScale = 0xffffff;
1064
1065 (void) dims;
1066 ASSERT(dstFormat == MESA_FORMAT_X8_Z24);
1067
1068 {
1069 /* general path */
1070 GLint img, row;
1071 for (img = 0; img < srcDepth; img++) {
1072 GLubyte *dstRow = dstSlices[img];
1073 for (row = 0; row < srcHeight; row++) {
1074 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1075 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1076 _mesa_unpack_depth_span(ctx, srcWidth,
1077 GL_UNSIGNED_INT, (GLuint *) dstRow,
1078 depthScale, srcType, src, srcPacking);
1079 dstRow += dstRowStride;
1080 }
1081 }
1082 }
1083 return GL_TRUE;
1084 }
1085
1086
1087 /**
1088 * Store a 24-bit integer depth component texture image.
1089 */
1090 static GLboolean
_mesa_texstore_z24_x8(TEXSTORE_PARAMS)1091 _mesa_texstore_z24_x8(TEXSTORE_PARAMS)
1092 {
1093 const GLuint depthScale = 0xffffff;
1094
1095 (void) dims;
1096 ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
1097
1098 {
1099 /* general path */
1100 GLint img, row;
1101 for (img = 0; img < srcDepth; img++) {
1102 GLubyte *dstRow = dstSlices[img];
1103 for (row = 0; row < srcHeight; row++) {
1104 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1105 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1106 GLuint *dst = (GLuint *) dstRow;
1107 GLint i;
1108 _mesa_unpack_depth_span(ctx, srcWidth,
1109 GL_UNSIGNED_INT, dst,
1110 depthScale, srcType, src, srcPacking);
1111 for (i = 0; i < srcWidth; i++)
1112 dst[i] <<= 8;
1113 dstRow += dstRowStride;
1114 }
1115 }
1116 }
1117 return GL_TRUE;
1118 }
1119
1120
1121 /**
1122 * Store a 16-bit integer depth component texture image.
1123 */
1124 static GLboolean
_mesa_texstore_z16(TEXSTORE_PARAMS)1125 _mesa_texstore_z16(TEXSTORE_PARAMS)
1126 {
1127 const GLuint depthScale = 0xffff;
1128 (void) dims;
1129 ASSERT(dstFormat == MESA_FORMAT_Z16);
1130 ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
1131
1132 if (ctx->Pixel.DepthScale == 1.0f &&
1133 ctx->Pixel.DepthBias == 0.0f &&
1134 !srcPacking->SwapBytes &&
1135 baseInternalFormat == GL_DEPTH_COMPONENT &&
1136 srcFormat == GL_DEPTH_COMPONENT &&
1137 srcType == GL_UNSIGNED_SHORT) {
1138 /* simple memcpy path */
1139 memcpy_texture(ctx, dims,
1140 dstFormat,
1141 dstRowStride, dstSlices,
1142 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1143 srcAddr, srcPacking);
1144 }
1145 else {
1146 /* general path */
1147 GLint img, row;
1148 for (img = 0; img < srcDepth; img++) {
1149 GLubyte *dstRow = dstSlices[img];
1150 for (row = 0; row < srcHeight; row++) {
1151 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1152 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1153 GLushort *dst16 = (GLushort *) dstRow;
1154 _mesa_unpack_depth_span(ctx, srcWidth,
1155 GL_UNSIGNED_SHORT, dst16, depthScale,
1156 srcType, src, srcPacking);
1157 dstRow += dstRowStride;
1158 }
1159 }
1160 }
1161 return GL_TRUE;
1162 }
1163
1164
1165 /**
1166 * Store an rgb565 or rgb565_rev texture image.
1167 */
1168 static GLboolean
_mesa_texstore_rgb565(TEXSTORE_PARAMS)1169 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
1170 {
1171 ASSERT(dstFormat == MESA_FORMAT_RGB565 ||
1172 dstFormat == MESA_FORMAT_RGB565_REV);
1173 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1174
1175 if (!ctx->_ImageTransferState &&
1176 baseInternalFormat == GL_RGB &&
1177 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1178 srcPacking->SwapBytes)) {
1179 /* simple memcpy path */
1180 memcpy_texture(ctx, dims,
1181 dstFormat,
1182 dstRowStride, dstSlices,
1183 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1184 srcAddr, srcPacking);
1185 }
1186 else if (!ctx->_ImageTransferState &&
1187 !srcPacking->SwapBytes &&
1188 baseInternalFormat == GL_RGB &&
1189 srcFormat == GL_RGB &&
1190 srcType == GL_UNSIGNED_BYTE &&
1191 dims == 2) {
1192 /* do optimized tex store */
1193 const GLint srcRowStride =
1194 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1195 const GLubyte *src = (const GLubyte *)
1196 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
1197 srcFormat, srcType, 0, 0, 0);
1198 GLubyte *dst = dstSlices[0];
1199 GLint row, col;
1200 for (row = 0; row < srcHeight; row++) {
1201 const GLubyte *srcUB = (const GLubyte *) src;
1202 GLushort *dstUS = (GLushort *) dst;
1203 /* check for byteswapped format */
1204 if (dstFormat == MESA_FORMAT_RGB565) {
1205 for (col = 0; col < srcWidth; col++) {
1206 dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
1207 srcUB += 3;
1208 }
1209 }
1210 else {
1211 for (col = 0; col < srcWidth; col++) {
1212 dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
1213 srcUB += 3;
1214 }
1215 }
1216 dst += dstRowStride;
1217 src += srcRowStride;
1218 }
1219 }
1220 else {
1221 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1222 dstFormat, dstRowStride, dstSlices,
1223 srcWidth, srcHeight, srcDepth,
1224 srcFormat, srcType, srcAddr, srcPacking);
1225 }
1226 return GL_TRUE;
1227 }
1228
1229
1230 /**
1231 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1232 */
1233 static GLboolean
_mesa_texstore_rgba8888(TEXSTORE_PARAMS)1234 _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
1235 {
1236 const GLboolean littleEndian = _mesa_little_endian();
1237
1238 ASSERT(dstFormat == MESA_FORMAT_RGBA8888 ||
1239 dstFormat == MESA_FORMAT_RGBA8888_REV ||
1240 dstFormat == MESA_FORMAT_RGBX8888 ||
1241 dstFormat == MESA_FORMAT_RGBX8888_REV);
1242 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1243
1244 if (!ctx->_ImageTransferState &&
1245 baseInternalFormat == GL_RGBA &&
1246 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1247 srcPacking->SwapBytes)) {
1248 /* simple memcpy path */
1249 memcpy_texture(ctx, dims,
1250 dstFormat,
1251 dstRowStride, dstSlices,
1252 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1253 srcAddr, srcPacking);
1254 }
1255 else if (!ctx->_ImageTransferState &&
1256 (srcType == GL_UNSIGNED_BYTE ||
1257 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1258 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1259 can_swizzle(baseInternalFormat) &&
1260 can_swizzle(srcFormat)) {
1261
1262 GLubyte dstmap[4];
1263
1264 /* dstmap - how to swizzle from RGBA to dst format:
1265 */
1266 if ((littleEndian && (dstFormat == MESA_FORMAT_RGBA8888 ||
1267 dstFormat == MESA_FORMAT_RGBX8888)) ||
1268 (!littleEndian && (dstFormat == MESA_FORMAT_RGBA8888_REV ||
1269 dstFormat == MESA_FORMAT_RGBX8888_REV))) {
1270 dstmap[3] = 0;
1271 dstmap[2] = 1;
1272 dstmap[1] = 2;
1273 dstmap[0] = 3;
1274 }
1275 else {
1276 dstmap[3] = 3;
1277 dstmap[2] = 2;
1278 dstmap[1] = 1;
1279 dstmap[0] = 0;
1280 }
1281
1282 _mesa_swizzle_ubyte_image(ctx, dims,
1283 srcFormat,
1284 srcType,
1285 baseInternalFormat,
1286 dstmap, 4,
1287 dstRowStride, dstSlices,
1288 srcWidth, srcHeight, srcDepth, srcAddr,
1289 srcPacking);
1290 }
1291 else {
1292 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1293 dstFormat, dstRowStride, dstSlices,
1294 srcWidth, srcHeight, srcDepth,
1295 srcFormat, srcType, srcAddr, srcPacking);
1296 }
1297 return GL_TRUE;
1298 }
1299
1300
1301 static GLboolean
_mesa_texstore_argb8888(TEXSTORE_PARAMS)1302 _mesa_texstore_argb8888(TEXSTORE_PARAMS)
1303 {
1304 const GLboolean littleEndian = _mesa_little_endian();
1305
1306 ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
1307 dstFormat == MESA_FORMAT_ARGB8888_REV ||
1308 dstFormat == MESA_FORMAT_XRGB8888 ||
1309 dstFormat == MESA_FORMAT_XRGB8888_REV );
1310 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1311
1312 if (!ctx->_ImageTransferState &&
1313 baseInternalFormat == GL_RGBA &&
1314 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1315 srcPacking->SwapBytes)) {
1316 /* simple memcpy path (big endian) */
1317 memcpy_texture(ctx, dims,
1318 dstFormat,
1319 dstRowStride, dstSlices,
1320 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1321 srcAddr, srcPacking);
1322 }
1323 else if (!ctx->_ImageTransferState &&
1324 !srcPacking->SwapBytes &&
1325 (dstFormat == MESA_FORMAT_ARGB8888 ||
1326 dstFormat == MESA_FORMAT_XRGB8888) &&
1327 srcFormat == GL_RGB &&
1328 (baseInternalFormat == GL_RGBA ||
1329 baseInternalFormat == GL_RGB) &&
1330 srcType == GL_UNSIGNED_BYTE) {
1331 int img, row, col;
1332 for (img = 0; img < srcDepth; img++) {
1333 const GLint srcRowStride =
1334 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1335 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1336 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1337 GLubyte *dstRow = dstSlices[img];
1338 for (row = 0; row < srcHeight; row++) {
1339 GLuint *d4 = (GLuint *) dstRow;
1340 for (col = 0; col < srcWidth; col++) {
1341 d4[col] = PACK_COLOR_8888(0xff,
1342 srcRow[col * 3 + RCOMP],
1343 srcRow[col * 3 + GCOMP],
1344 srcRow[col * 3 + BCOMP]);
1345 }
1346 dstRow += dstRowStride;
1347 srcRow += srcRowStride;
1348 }
1349 }
1350 }
1351 else if (!ctx->_ImageTransferState &&
1352 !srcPacking->SwapBytes &&
1353 dstFormat == MESA_FORMAT_ARGB8888 &&
1354 srcFormat == GL_LUMINANCE_ALPHA &&
1355 baseInternalFormat == GL_RGBA &&
1356 srcType == GL_UNSIGNED_BYTE) {
1357 /* special case of storing LA -> ARGB8888 */
1358 int img, row, col;
1359 const GLint srcRowStride =
1360 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1361 for (img = 0; img < srcDepth; img++) {
1362 const GLubyte *srcRow = (const GLubyte *)
1363 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth,
1364 srcHeight, srcFormat, srcType, img, 0, 0);
1365 GLubyte *dstRow = dstSlices[img];
1366 for (row = 0; row < srcHeight; row++) {
1367 GLuint *d4 = (GLuint *) dstRow;
1368 for (col = 0; col < srcWidth; col++) {
1369 GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1];
1370 d4[col] = PACK_COLOR_8888(a, l, l, l);
1371 }
1372 dstRow += dstRowStride;
1373 srcRow += srcRowStride;
1374 }
1375 }
1376 }
1377 else if (!ctx->_ImageTransferState &&
1378 !srcPacking->SwapBytes &&
1379 dstFormat == MESA_FORMAT_ARGB8888 &&
1380 srcFormat == GL_RGBA &&
1381 baseInternalFormat == GL_RGBA &&
1382 srcType == GL_UNSIGNED_BYTE) {
1383 /* same as above case, but src data has alpha too */
1384 GLint img, row, col;
1385 /* For some reason, streaming copies to write-combined regions
1386 * are extremely sensitive to the characteristics of how the
1387 * source data is retrieved. By reordering the source reads to
1388 * be in-order, the speed of this operation increases by half.
1389 * Strangely the same isn't required for the RGB path, above.
1390 */
1391 for (img = 0; img < srcDepth; img++) {
1392 const GLint srcRowStride =
1393 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1394 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1395 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1396 GLubyte *dstRow = dstSlices[img];
1397 for (row = 0; row < srcHeight; row++) {
1398 GLuint *d4 = (GLuint *) dstRow;
1399 for (col = 0; col < srcWidth; col++) {
1400 d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
1401 srcRow[col * 4 + RCOMP],
1402 srcRow[col * 4 + GCOMP],
1403 srcRow[col * 4 + BCOMP]);
1404 }
1405 dstRow += dstRowStride;
1406 srcRow += srcRowStride;
1407 }
1408 }
1409 }
1410 else if (!ctx->_ImageTransferState &&
1411 (srcType == GL_UNSIGNED_BYTE ||
1412 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1413 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1414 can_swizzle(baseInternalFormat) &&
1415 can_swizzle(srcFormat)) {
1416
1417 GLubyte dstmap[4];
1418
1419 /* dstmap - how to swizzle from RGBA to dst format:
1420 */
1421 if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1422 (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
1423 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
1424 (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
1425 dstmap[3] = 3; /* alpha */
1426 dstmap[2] = 0; /* red */
1427 dstmap[1] = 1; /* green */
1428 dstmap[0] = 2; /* blue */
1429 }
1430 else {
1431 assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
1432 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1433 (littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
1434 (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
1435 dstmap[3] = 2;
1436 dstmap[2] = 1;
1437 dstmap[1] = 0;
1438 dstmap[0] = 3;
1439 }
1440
1441 _mesa_swizzle_ubyte_image(ctx, dims,
1442 srcFormat,
1443 srcType,
1444 baseInternalFormat,
1445 dstmap, 4,
1446 dstRowStride,
1447 dstSlices,
1448 srcWidth, srcHeight, srcDepth, srcAddr,
1449 srcPacking);
1450 }
1451 else {
1452 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1453 dstFormat, dstRowStride, dstSlices,
1454 srcWidth, srcHeight, srcDepth,
1455 srcFormat, srcType, srcAddr, srcPacking);
1456 }
1457 return GL_TRUE;
1458 }
1459
1460
1461 static GLboolean
_mesa_texstore_rgb888(TEXSTORE_PARAMS)1462 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
1463 {
1464 ASSERT(dstFormat == MESA_FORMAT_RGB888);
1465 ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
1466
1467 if (!ctx->_ImageTransferState &&
1468 baseInternalFormat == GL_RGB &&
1469 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1470 srcPacking->SwapBytes)) {
1471 /* simple memcpy path */
1472 memcpy_texture(ctx, dims,
1473 dstFormat,
1474 dstRowStride, dstSlices,
1475 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1476 srcAddr, srcPacking);
1477 }
1478 else if (!ctx->_ImageTransferState &&
1479 !srcPacking->SwapBytes &&
1480 srcFormat == GL_RGBA &&
1481 srcType == GL_UNSIGNED_BYTE) {
1482 /* extract RGB from RGBA */
1483 GLint img, row, col;
1484 for (img = 0; img < srcDepth; img++) {
1485 const GLint srcRowStride =
1486 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1487 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1488 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1489 GLubyte *dstRow = dstSlices[img];
1490 for (row = 0; row < srcHeight; row++) {
1491 for (col = 0; col < srcWidth; col++) {
1492 dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1493 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1494 dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1495 }
1496 dstRow += dstRowStride;
1497 srcRow += srcRowStride;
1498 }
1499 }
1500 }
1501 else if (!ctx->_ImageTransferState &&
1502 srcType == GL_UNSIGNED_BYTE &&
1503 can_swizzle(baseInternalFormat) &&
1504 can_swizzle(srcFormat)) {
1505
1506 GLubyte dstmap[4];
1507
1508 /* dstmap - how to swizzle from RGBA to dst format:
1509 */
1510 dstmap[0] = 2;
1511 dstmap[1] = 1;
1512 dstmap[2] = 0;
1513 dstmap[3] = ONE; /* ? */
1514
1515 _mesa_swizzle_ubyte_image(ctx, dims,
1516 srcFormat,
1517 srcType,
1518 baseInternalFormat,
1519 dstmap, 3,
1520 dstRowStride, dstSlices,
1521 srcWidth, srcHeight, srcDepth, srcAddr,
1522 srcPacking);
1523 }
1524 else {
1525 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1526 dstFormat, dstRowStride, dstSlices,
1527 srcWidth, srcHeight, srcDepth,
1528 srcFormat, srcType, srcAddr, srcPacking);
1529 }
1530 return GL_TRUE;
1531 }
1532
1533
1534 static GLboolean
_mesa_texstore_bgr888(TEXSTORE_PARAMS)1535 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
1536 {
1537 ASSERT(dstFormat == MESA_FORMAT_BGR888);
1538 ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
1539
1540 if (!ctx->_ImageTransferState &&
1541 baseInternalFormat == GL_RGB &&
1542 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1543 srcPacking->SwapBytes)) {
1544 /* simple memcpy path */
1545 memcpy_texture(ctx, dims,
1546 dstFormat,
1547 dstRowStride, dstSlices,
1548 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1549 srcAddr, srcPacking);
1550 }
1551 else if (!ctx->_ImageTransferState &&
1552 !srcPacking->SwapBytes &&
1553 srcFormat == GL_RGBA &&
1554 srcType == GL_UNSIGNED_BYTE) {
1555 /* extract BGR from RGBA */
1556 int img, row, col;
1557 for (img = 0; img < srcDepth; img++) {
1558 const GLint srcRowStride =
1559 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1560 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1561 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1562 GLubyte *dstRow = dstSlices[img];
1563 for (row = 0; row < srcHeight; row++) {
1564 for (col = 0; col < srcWidth; col++) {
1565 dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1566 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1567 dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1568 }
1569 dstRow += dstRowStride;
1570 srcRow += srcRowStride;
1571 }
1572 }
1573 }
1574 else if (!ctx->_ImageTransferState &&
1575 srcType == GL_UNSIGNED_BYTE &&
1576 can_swizzle(baseInternalFormat) &&
1577 can_swizzle(srcFormat)) {
1578
1579 GLubyte dstmap[4];
1580
1581 /* dstmap - how to swizzle from RGBA to dst format:
1582 */
1583 dstmap[0] = 0;
1584 dstmap[1] = 1;
1585 dstmap[2] = 2;
1586 dstmap[3] = ONE; /* ? */
1587
1588 _mesa_swizzle_ubyte_image(ctx, dims,
1589 srcFormat,
1590 srcType,
1591 baseInternalFormat,
1592 dstmap, 3,
1593 dstRowStride, dstSlices,
1594 srcWidth, srcHeight, srcDepth, srcAddr,
1595 srcPacking);
1596 }
1597 else {
1598 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1599 dstFormat, dstRowStride, dstSlices,
1600 srcWidth, srcHeight, srcDepth,
1601 srcFormat, srcType, srcAddr, srcPacking);
1602 }
1603 return GL_TRUE;
1604 }
1605
1606
1607 static GLboolean
_mesa_texstore_argb4444(TEXSTORE_PARAMS)1608 _mesa_texstore_argb4444(TEXSTORE_PARAMS)
1609 {
1610 ASSERT(dstFormat == MESA_FORMAT_ARGB4444 ||
1611 dstFormat == MESA_FORMAT_ARGB4444_REV);
1612 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1613
1614 if (!ctx->_ImageTransferState &&
1615 baseInternalFormat == GL_RGBA &&
1616 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1617 srcPacking->SwapBytes)) {
1618 /* simple memcpy path */
1619 memcpy_texture(ctx, dims,
1620 dstFormat,
1621 dstRowStride, dstSlices,
1622 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1623 srcAddr, srcPacking);
1624 }
1625 else {
1626 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1627 dstFormat, dstRowStride, dstSlices,
1628 srcWidth, srcHeight, srcDepth,
1629 srcFormat, srcType, srcAddr, srcPacking);
1630 }
1631 return GL_TRUE;
1632 }
1633
1634 static GLboolean
_mesa_texstore_rgba5551(TEXSTORE_PARAMS)1635 _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
1636 {
1637 ASSERT(dstFormat == MESA_FORMAT_RGBA5551);
1638 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1639
1640 if (!ctx->_ImageTransferState &&
1641 baseInternalFormat == GL_RGBA &&
1642 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1643 srcPacking->SwapBytes)) {
1644 /* simple memcpy path */
1645 memcpy_texture(ctx, dims,
1646 dstFormat,
1647 dstRowStride, dstSlices,
1648 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1649 srcAddr, srcPacking);
1650 }
1651 else {
1652 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1653 dstFormat, dstRowStride, dstSlices,
1654 srcWidth, srcHeight, srcDepth,
1655 srcFormat, srcType, srcAddr, srcPacking);
1656 }
1657 return GL_TRUE;
1658 }
1659
1660 static GLboolean
_mesa_texstore_argb1555(TEXSTORE_PARAMS)1661 _mesa_texstore_argb1555(TEXSTORE_PARAMS)
1662 {
1663 ASSERT(dstFormat == MESA_FORMAT_ARGB1555 ||
1664 dstFormat == MESA_FORMAT_ARGB1555_REV);
1665 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1666
1667 if (!ctx->_ImageTransferState &&
1668 baseInternalFormat == GL_RGBA &&
1669 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1670 srcPacking->SwapBytes)) {
1671 /* simple memcpy path */
1672 memcpy_texture(ctx, dims,
1673 dstFormat,
1674 dstRowStride, dstSlices,
1675 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1676 srcAddr, srcPacking);
1677 }
1678 else {
1679 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1680 dstFormat, dstRowStride, dstSlices,
1681 srcWidth, srcHeight, srcDepth,
1682 srcFormat, srcType, srcAddr, srcPacking);
1683 }
1684 return GL_TRUE;
1685 }
1686
1687
1688 static GLboolean
_mesa_texstore_argb2101010(TEXSTORE_PARAMS)1689 _mesa_texstore_argb2101010(TEXSTORE_PARAMS)
1690 {
1691 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1692
1693 ASSERT(dstFormat == MESA_FORMAT_ARGB2101010);
1694 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1695
1696 if (!ctx->_ImageTransferState &&
1697 baseInternalFormat == GL_RGBA &&
1698 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1699 srcPacking->SwapBytes)) {
1700 /* simple memcpy path */
1701 memcpy_texture(ctx, dims,
1702 dstFormat,
1703 dstRowStride, dstSlices,
1704 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1705 srcAddr, srcPacking);
1706 }
1707 else {
1708 /* general path */
1709 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
1710 baseInternalFormat,
1711 baseFormat,
1712 srcWidth, srcHeight, srcDepth,
1713 srcFormat, srcType, srcAddr,
1714 srcPacking,
1715 ctx->_ImageTransferState);
1716 const GLfloat *src = tempImage;
1717 GLint img, row, col;
1718 if (!tempImage)
1719 return GL_FALSE;
1720 for (img = 0; img < srcDepth; img++) {
1721 GLubyte *dstRow = dstSlices[img];
1722 if (baseInternalFormat == GL_RGBA) {
1723 for (row = 0; row < srcHeight; row++) {
1724 GLuint *dstUI = (GLuint *) dstRow;
1725 for (col = 0; col < srcWidth; col++) {
1726 GLushort a,r,g,b;
1727
1728 UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
1729 UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
1730 UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
1731 UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
1732 dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b);
1733 src += 4;
1734 }
1735 dstRow += dstRowStride;
1736 }
1737 } else if (baseInternalFormat == GL_RGB) {
1738 for (row = 0; row < srcHeight; row++) {
1739 GLuint *dstUI = (GLuint *) dstRow;
1740 for (col = 0; col < srcWidth; col++) {
1741 GLushort r,g,b;
1742
1743 UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
1744 UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
1745 UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
1746 dstUI[col] = PACK_COLOR_2101010_US(0xffff, r, g, b);
1747 src += 4;
1748 }
1749 dstRow += dstRowStride;
1750 }
1751 } else {
1752 ASSERT(0);
1753 }
1754 }
1755 free((void *) tempImage);
1756 }
1757 return GL_TRUE;
1758 }
1759
1760
1761 /**
1762 * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats.
1763 */
1764 static GLboolean
_mesa_texstore_unorm44(TEXSTORE_PARAMS)1765 _mesa_texstore_unorm44(TEXSTORE_PARAMS)
1766 {
1767 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1768
1769 ASSERT(dstFormat == MESA_FORMAT_AL44);
1770 ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
1771
1772 {
1773 /* general path */
1774 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1775 baseInternalFormat,
1776 baseFormat,
1777 srcWidth, srcHeight, srcDepth,
1778 srcFormat, srcType, srcAddr,
1779 srcPacking);
1780 const GLubyte *src = tempImage;
1781 GLint img, row, col;
1782 if (!tempImage)
1783 return GL_FALSE;
1784 for (img = 0; img < srcDepth; img++) {
1785 GLubyte *dstRow = dstSlices[img];
1786 for (row = 0; row < srcHeight; row++) {
1787 GLubyte *dstUS = (GLubyte *) dstRow;
1788 for (col = 0; col < srcWidth; col++) {
1789 /* src[0] is luminance, src[1] is alpha */
1790 dstUS[col] = PACK_COLOR_44( src[1],
1791 src[0] );
1792 src += 2;
1793 }
1794 dstRow += dstRowStride;
1795 }
1796 }
1797 free((void *) tempImage);
1798 }
1799 return GL_TRUE;
1800 }
1801
1802
1803 /**
1804 * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats.
1805 */
1806 static GLboolean
_mesa_texstore_unorm88(TEXSTORE_PARAMS)1807 _mesa_texstore_unorm88(TEXSTORE_PARAMS)
1808 {
1809 const GLboolean littleEndian = _mesa_little_endian();
1810 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1811
1812 ASSERT(dstFormat == MESA_FORMAT_AL88 ||
1813 dstFormat == MESA_FORMAT_AL88_REV ||
1814 dstFormat == MESA_FORMAT_GR88 ||
1815 dstFormat == MESA_FORMAT_RG88);
1816 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1817
1818 if (!ctx->_ImageTransferState &&
1819 !srcPacking->SwapBytes &&
1820 ((dstFormat == MESA_FORMAT_AL88 &&
1821 baseInternalFormat == GL_LUMINANCE_ALPHA &&
1822 srcFormat == GL_LUMINANCE_ALPHA) ||
1823 (dstFormat == MESA_FORMAT_GR88 &&
1824 baseInternalFormat == srcFormat)) &&
1825 srcType == GL_UNSIGNED_BYTE &&
1826 littleEndian) {
1827 /* simple memcpy path */
1828 memcpy_texture(ctx, dims,
1829 dstFormat,
1830 dstRowStride, dstSlices,
1831 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1832 srcAddr, srcPacking);
1833 }
1834 else if (!ctx->_ImageTransferState &&
1835 littleEndian &&
1836 srcType == GL_UNSIGNED_BYTE &&
1837 can_swizzle(baseInternalFormat) &&
1838 can_swizzle(srcFormat)) {
1839 GLubyte dstmap[4];
1840
1841 /* dstmap - how to swizzle from RGBA to dst format:
1842 */
1843 if (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV) {
1844 if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
1845 (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
1846 dstmap[0] = 0;
1847 dstmap[1] = 3;
1848 }
1849 else {
1850 dstmap[0] = 3;
1851 dstmap[1] = 0;
1852 }
1853 }
1854 else {
1855 if ((littleEndian && dstFormat == MESA_FORMAT_GR88) ||
1856 (!littleEndian && dstFormat == MESA_FORMAT_RG88)) {
1857 dstmap[0] = 0;
1858 dstmap[1] = 1;
1859 }
1860 else {
1861 dstmap[0] = 1;
1862 dstmap[1] = 0;
1863 }
1864 }
1865 dstmap[2] = ZERO; /* ? */
1866 dstmap[3] = ONE; /* ? */
1867
1868 _mesa_swizzle_ubyte_image(ctx, dims,
1869 srcFormat,
1870 srcType,
1871 baseInternalFormat,
1872 dstmap, 2,
1873 dstRowStride, dstSlices,
1874 srcWidth, srcHeight, srcDepth, srcAddr,
1875 srcPacking);
1876 }
1877 else {
1878 /* general path */
1879 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1880 baseInternalFormat,
1881 baseFormat,
1882 srcWidth, srcHeight, srcDepth,
1883 srcFormat, srcType, srcAddr,
1884 srcPacking);
1885 const GLubyte *src = tempImage;
1886 GLint img, row, col;
1887 if (!tempImage)
1888 return GL_FALSE;
1889 for (img = 0; img < srcDepth; img++) {
1890 GLubyte *dstRow = dstSlices[img];
1891 for (row = 0; row < srcHeight; row++) {
1892 GLushort *dstUS = (GLushort *) dstRow;
1893 if (dstFormat == MESA_FORMAT_AL88 ||
1894 dstFormat == MESA_FORMAT_GR88) {
1895 for (col = 0; col < srcWidth; col++) {
1896 /* src[0] is luminance (or R), src[1] is alpha (or G) */
1897 dstUS[col] = PACK_COLOR_88( src[1],
1898 src[0] );
1899 src += 2;
1900 }
1901 }
1902 else {
1903 for (col = 0; col < srcWidth; col++) {
1904 /* src[0] is luminance (or R), src[1] is alpha (or G) */
1905 dstUS[col] = PACK_COLOR_88_REV( src[1],
1906 src[0] );
1907 src += 2;
1908 }
1909 }
1910 dstRow += dstRowStride;
1911 }
1912 }
1913 free((void *) tempImage);
1914 }
1915 return GL_TRUE;
1916 }
1917
1918
1919 /**
1920 * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats.
1921 */
1922 static GLboolean
_mesa_texstore_unorm1616(TEXSTORE_PARAMS)1923 _mesa_texstore_unorm1616(TEXSTORE_PARAMS)
1924 {
1925 const GLboolean littleEndian = _mesa_little_endian();
1926 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1927
1928 ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
1929 dstFormat == MESA_FORMAT_AL1616_REV ||
1930 dstFormat == MESA_FORMAT_RG1616 ||
1931 dstFormat == MESA_FORMAT_RG1616_REV);
1932 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1933
1934 if (!ctx->_ImageTransferState &&
1935 !srcPacking->SwapBytes &&
1936 ((dstFormat == MESA_FORMAT_AL1616 &&
1937 baseInternalFormat == GL_LUMINANCE_ALPHA &&
1938 srcFormat == GL_LUMINANCE_ALPHA) ||
1939 (dstFormat == MESA_FORMAT_RG1616 &&
1940 baseInternalFormat == srcFormat)) &&
1941 srcType == GL_UNSIGNED_SHORT &&
1942 littleEndian) {
1943 /* simple memcpy path */
1944 memcpy_texture(ctx, dims,
1945 dstFormat,
1946 dstRowStride, dstSlices,
1947 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1948 srcAddr, srcPacking);
1949 }
1950 else {
1951 /* general path */
1952 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
1953 baseInternalFormat,
1954 baseFormat,
1955 srcWidth, srcHeight, srcDepth,
1956 srcFormat, srcType, srcAddr,
1957 srcPacking,
1958 ctx->_ImageTransferState);
1959 const GLfloat *src = tempImage;
1960 GLint img, row, col;
1961 if (!tempImage)
1962 return GL_FALSE;
1963 for (img = 0; img < srcDepth; img++) {
1964 GLubyte *dstRow = dstSlices[img];
1965 for (row = 0; row < srcHeight; row++) {
1966 GLuint *dstUI = (GLuint *) dstRow;
1967 if (dstFormat == MESA_FORMAT_AL1616 ||
1968 dstFormat == MESA_FORMAT_RG1616) {
1969 for (col = 0; col < srcWidth; col++) {
1970 GLushort l, a;
1971
1972 UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
1973 UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
1974 dstUI[col] = PACK_COLOR_1616(a, l);
1975 src += 2;
1976 }
1977 }
1978 else {
1979 for (col = 0; col < srcWidth; col++) {
1980 GLushort l, a;
1981
1982 UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
1983 UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
1984 dstUI[col] = PACK_COLOR_1616_REV(a, l);
1985 src += 2;
1986 }
1987 }
1988 dstRow += dstRowStride;
1989 }
1990 }
1991 free((void *) tempImage);
1992 }
1993 return GL_TRUE;
1994 }
1995
1996
1997 /* Texstore for R16, A16, L16, I16. */
1998 static GLboolean
_mesa_texstore_unorm16(TEXSTORE_PARAMS)1999 _mesa_texstore_unorm16(TEXSTORE_PARAMS)
2000 {
2001 const GLboolean littleEndian = _mesa_little_endian();
2002 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2003
2004 ASSERT(dstFormat == MESA_FORMAT_R16 ||
2005 dstFormat == MESA_FORMAT_A16 ||
2006 dstFormat == MESA_FORMAT_L16 ||
2007 dstFormat == MESA_FORMAT_I16);
2008 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2009
2010 if (!ctx->_ImageTransferState &&
2011 !srcPacking->SwapBytes &&
2012 baseInternalFormat == srcFormat &&
2013 srcType == GL_UNSIGNED_SHORT &&
2014 littleEndian) {
2015 /* simple memcpy path */
2016 memcpy_texture(ctx, dims,
2017 dstFormat,
2018 dstRowStride, dstSlices,
2019 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2020 srcAddr, srcPacking);
2021 }
2022 else {
2023 /* general path */
2024 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2025 baseInternalFormat,
2026 baseFormat,
2027 srcWidth, srcHeight, srcDepth,
2028 srcFormat, srcType, srcAddr,
2029 srcPacking,
2030 ctx->_ImageTransferState);
2031 const GLfloat *src = tempImage;
2032 GLint img, row, col;
2033 if (!tempImage)
2034 return GL_FALSE;
2035 for (img = 0; img < srcDepth; img++) {
2036 GLubyte *dstRow = dstSlices[img];
2037 for (row = 0; row < srcHeight; row++) {
2038 GLushort *dstUS = (GLushort *) dstRow;
2039 for (col = 0; col < srcWidth; col++) {
2040 GLushort r;
2041
2042 UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
2043 dstUS[col] = r;
2044 src += 1;
2045 }
2046 dstRow += dstRowStride;
2047 }
2048 }
2049 free((void *) tempImage);
2050 }
2051 return GL_TRUE;
2052 }
2053
2054
2055 static GLboolean
_mesa_texstore_rgba_16(TEXSTORE_PARAMS)2056 _mesa_texstore_rgba_16(TEXSTORE_PARAMS)
2057 {
2058 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2059
2060 ASSERT(dstFormat == MESA_FORMAT_RGBA_16);
2061 ASSERT(_mesa_get_format_bytes(dstFormat) == 8);
2062
2063 if (!ctx->_ImageTransferState &&
2064 !srcPacking->SwapBytes &&
2065 baseInternalFormat == GL_RGBA &&
2066 srcFormat == GL_RGBA &&
2067 srcType == GL_UNSIGNED_SHORT) {
2068 /* simple memcpy path */
2069 memcpy_texture(ctx, dims,
2070 dstFormat,
2071 dstRowStride, dstSlices,
2072 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2073 srcAddr, srcPacking);
2074 }
2075 else {
2076 /* general path */
2077 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2078 baseInternalFormat,
2079 baseFormat,
2080 srcWidth, srcHeight, srcDepth,
2081 srcFormat, srcType, srcAddr,
2082 srcPacking,
2083 ctx->_ImageTransferState);
2084 const GLfloat *src = tempImage;
2085 GLint img, row, col;
2086 if (!tempImage)
2087 return GL_FALSE;
2088 for (img = 0; img < srcDepth; img++) {
2089 GLubyte *dstRow = dstSlices[img];
2090 for (row = 0; row < srcHeight; row++) {
2091 GLushort *dstUS = (GLushort *) dstRow;
2092 for (col = 0; col < srcWidth; col++) {
2093 GLushort r, g, b, a;
2094
2095 UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
2096 UNCLAMPED_FLOAT_TO_USHORT(g, src[1]);
2097 UNCLAMPED_FLOAT_TO_USHORT(b, src[2]);
2098 UNCLAMPED_FLOAT_TO_USHORT(a, src[3]);
2099 dstUS[col*4+0] = r;
2100 dstUS[col*4+1] = g;
2101 dstUS[col*4+2] = b;
2102 dstUS[col*4+3] = a;
2103 src += 4;
2104 }
2105 dstRow += dstRowStride;
2106 }
2107 }
2108 free((void *) tempImage);
2109 }
2110 return GL_TRUE;
2111 }
2112
2113
2114 static GLboolean
_mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)2115 _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)
2116 {
2117 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2118
2119 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGB_16 ||
2120 dstFormat == MESA_FORMAT_SIGNED_RGBA_16);
2121
2122 if (!ctx->_ImageTransferState &&
2123 !srcPacking->SwapBytes &&
2124 baseInternalFormat == GL_RGBA &&
2125 dstFormat == MESA_FORMAT_SIGNED_RGBA_16 &&
2126 srcFormat == GL_RGBA &&
2127 srcType == GL_SHORT) {
2128 /* simple memcpy path */
2129 memcpy_texture(ctx, dims,
2130 dstFormat,
2131 dstRowStride, dstSlices,
2132 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2133 srcAddr, srcPacking);
2134 }
2135 else {
2136 /* general path */
2137 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2138 baseInternalFormat,
2139 baseFormat,
2140 srcWidth, srcHeight, srcDepth,
2141 srcFormat, srcType, srcAddr,
2142 srcPacking,
2143 ctx->_ImageTransferState);
2144 const GLfloat *src = tempImage;
2145 const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2;
2146 GLint img, row, col;
2147
2148 if (!tempImage)
2149 return GL_FALSE;
2150
2151 /* Note: tempImage is always float[4] / RGBA. We convert to 1, 2,
2152 * 3 or 4 components/pixel here.
2153 */
2154 for (img = 0; img < srcDepth; img++) {
2155 GLubyte *dstRow = dstSlices[img];
2156 for (row = 0; row < srcHeight; row++) {
2157 GLshort *dstRowS = (GLshort *) dstRow;
2158 if (dstFormat == MESA_FORMAT_SIGNED_RGBA_16) {
2159 for (col = 0; col < srcWidth; col++) {
2160 GLuint c;
2161 for (c = 0; c < comps; c++) {
2162 GLshort p;
2163 UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]);
2164 dstRowS[col * comps + c] = p;
2165 }
2166 }
2167 dstRow += dstRowStride;
2168 src += 4 * srcWidth;
2169 } else {
2170 for (col = 0; col < srcWidth; col++) {
2171 GLuint c;
2172 for (c = 0; c < comps; c++) {
2173 GLshort p;
2174 UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]);
2175 dstRowS[col * comps + c] = p;
2176 }
2177 }
2178 dstRow += dstRowStride;
2179 src += 3 * srcWidth;
2180 }
2181 }
2182 }
2183 free((void *) tempImage);
2184 }
2185 return GL_TRUE;
2186 }
2187
2188
2189 static GLboolean
_mesa_texstore_rgb332(TEXSTORE_PARAMS)2190 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
2191 {
2192 ASSERT(dstFormat == MESA_FORMAT_RGB332);
2193 ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
2194
2195 if (!ctx->_ImageTransferState &&
2196 baseInternalFormat == GL_RGB &&
2197 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
2198 srcPacking->SwapBytes)) {
2199 /* simple memcpy path */
2200 memcpy_texture(ctx, dims,
2201 dstFormat,
2202 dstRowStride, dstSlices,
2203 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2204 srcAddr, srcPacking);
2205 }
2206 else {
2207 return store_ubyte_texture(ctx, dims, baseInternalFormat,
2208 dstFormat, dstRowStride, dstSlices,
2209 srcWidth, srcHeight, srcDepth,
2210 srcFormat, srcType, srcAddr, srcPacking);
2211 }
2212 return GL_TRUE;
2213 }
2214
2215
2216 /**
2217 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2218 */
2219 static GLboolean
_mesa_texstore_unorm8(TEXSTORE_PARAMS)2220 _mesa_texstore_unorm8(TEXSTORE_PARAMS)
2221 {
2222 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2223
2224 ASSERT(dstFormat == MESA_FORMAT_A8 ||
2225 dstFormat == MESA_FORMAT_L8 ||
2226 dstFormat == MESA_FORMAT_I8 ||
2227 dstFormat == MESA_FORMAT_R8);
2228 ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
2229
2230 if (!ctx->_ImageTransferState &&
2231 !srcPacking->SwapBytes &&
2232 baseInternalFormat == srcFormat &&
2233 srcType == GL_UNSIGNED_BYTE) {
2234 /* simple memcpy path */
2235 memcpy_texture(ctx, dims,
2236 dstFormat,
2237 dstRowStride, dstSlices,
2238 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2239 srcAddr, srcPacking);
2240 }
2241 else if (!ctx->_ImageTransferState &&
2242 srcType == GL_UNSIGNED_BYTE &&
2243 can_swizzle(baseInternalFormat) &&
2244 can_swizzle(srcFormat)) {
2245 GLubyte dstmap[4];
2246
2247 /* dstmap - how to swizzle from RGBA to dst format:
2248 */
2249 if (dstFormat == MESA_FORMAT_A8) {
2250 dstmap[0] = 3;
2251 }
2252 else {
2253 dstmap[0] = 0;
2254 }
2255 dstmap[1] = ZERO; /* ? */
2256 dstmap[2] = ZERO; /* ? */
2257 dstmap[3] = ONE; /* ? */
2258
2259 _mesa_swizzle_ubyte_image(ctx, dims,
2260 srcFormat,
2261 srcType,
2262 baseInternalFormat,
2263 dstmap, 1,
2264 dstRowStride, dstSlices,
2265 srcWidth, srcHeight, srcDepth, srcAddr,
2266 srcPacking);
2267 }
2268 else {
2269 /* general path */
2270 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
2271 baseInternalFormat,
2272 baseFormat,
2273 srcWidth, srcHeight, srcDepth,
2274 srcFormat, srcType, srcAddr,
2275 srcPacking);
2276 const GLubyte *src = tempImage;
2277 GLint img, row, col;
2278 if (!tempImage)
2279 return GL_FALSE;
2280 for (img = 0; img < srcDepth; img++) {
2281 GLubyte *dstRow = dstSlices[img];
2282 for (row = 0; row < srcHeight; row++) {
2283 for (col = 0; col < srcWidth; col++) {
2284 dstRow[col] = src[col];
2285 }
2286 dstRow += dstRowStride;
2287 src += srcWidth;
2288 }
2289 }
2290 free((void *) tempImage);
2291 }
2292 return GL_TRUE;
2293 }
2294
2295
2296
2297 /**
2298 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2299 */
2300 static GLboolean
_mesa_texstore_ycbcr(TEXSTORE_PARAMS)2301 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
2302 {
2303 const GLboolean littleEndian = _mesa_little_endian();
2304
2305 (void) ctx; (void) dims; (void) baseInternalFormat;
2306
2307 ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
2308 (dstFormat == MESA_FORMAT_YCBCR_REV));
2309 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2310 ASSERT(ctx->Extensions.MESA_ycbcr_texture);
2311 ASSERT(srcFormat == GL_YCBCR_MESA);
2312 ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
2313 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
2314 ASSERT(baseInternalFormat == GL_YCBCR_MESA);
2315
2316 /* always just memcpy since no pixel transfer ops apply */
2317 memcpy_texture(ctx, dims,
2318 dstFormat,
2319 dstRowStride, dstSlices,
2320 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2321 srcAddr, srcPacking);
2322
2323 /* Check if we need byte swapping */
2324 /* XXX the logic here _might_ be wrong */
2325 if (srcPacking->SwapBytes ^
2326 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
2327 (dstFormat == MESA_FORMAT_YCBCR_REV) ^
2328 !littleEndian) {
2329 GLint img, row;
2330 for (img = 0; img < srcDepth; img++) {
2331 GLubyte *dstRow = dstSlices[img];
2332 for (row = 0; row < srcHeight; row++) {
2333 _mesa_swap2((GLushort *) dstRow, srcWidth);
2334 dstRow += dstRowStride;
2335 }
2336 }
2337 }
2338 return GL_TRUE;
2339 }
2340
2341 static GLboolean
_mesa_texstore_dudv8(TEXSTORE_PARAMS)2342 _mesa_texstore_dudv8(TEXSTORE_PARAMS)
2343 {
2344 const GLboolean littleEndian = _mesa_little_endian();
2345 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2346
2347 ASSERT(dstFormat == MESA_FORMAT_DUDV8);
2348 ASSERT(texelBytes == 2);
2349 ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
2350 ASSERT((srcFormat == GL_DU8DV8_ATI) ||
2351 (srcFormat == GL_DUDV_ATI));
2352 ASSERT(baseInternalFormat == GL_DUDV_ATI);
2353
2354 if (!srcPacking->SwapBytes && srcType == GL_BYTE &&
2355 littleEndian) {
2356 /* simple memcpy path */
2357 memcpy_texture(ctx, dims,
2358 dstFormat,
2359 dstRowStride, dstSlices,
2360 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2361 srcAddr, srcPacking);
2362 }
2363 else if (srcType == GL_BYTE) {
2364 GLubyte dstmap[4];
2365
2366 /* dstmap - how to swizzle from RGBA to dst format:
2367 */
2368 if (littleEndian) {
2369 dstmap[0] = 0;
2370 dstmap[1] = 3;
2371 }
2372 else {
2373 dstmap[0] = 3;
2374 dstmap[1] = 0;
2375 }
2376 dstmap[2] = ZERO; /* ? */
2377 dstmap[3] = ONE; /* ? */
2378
2379 _mesa_swizzle_ubyte_image(ctx, dims,
2380 GL_LUMINANCE_ALPHA, /* hack */
2381 GL_UNSIGNED_BYTE, /* hack */
2382 GL_LUMINANCE_ALPHA, /* hack */
2383 dstmap, 2,
2384 dstRowStride, dstSlices,
2385 srcWidth, srcHeight, srcDepth, srcAddr,
2386 srcPacking);
2387 }
2388 else {
2389 /* general path - note this is defined for 2d textures only */
2390 const GLint components = _mesa_components_in_format(baseInternalFormat);
2391 const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
2392 srcFormat, srcType);
2393 GLbyte *tempImage, *dst, *src;
2394 GLint row;
2395
2396 tempImage = (GLbyte *) malloc(srcWidth * srcHeight * srcDepth
2397 * components * sizeof(GLbyte));
2398 if (!tempImage)
2399 return GL_FALSE;
2400
2401 src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2402 srcWidth, srcHeight,
2403 srcFormat, srcType,
2404 0, 0, 0);
2405
2406 dst = tempImage;
2407 for (row = 0; row < srcHeight; row++) {
2408 _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
2409 dst, srcFormat, srcType, src,
2410 srcPacking, 0);
2411 dst += srcWidth * components;
2412 src += srcStride;
2413 }
2414
2415 src = tempImage;
2416 dst = (GLbyte *) dstSlices[0];
2417 for (row = 0; row < srcHeight; row++) {
2418 memcpy(dst, src, srcWidth * texelBytes);
2419 dst += dstRowStride;
2420 src += srcWidth * texelBytes;
2421 }
2422 free((void *) tempImage);
2423 }
2424 return GL_TRUE;
2425 }
2426
2427
2428 /**
2429 * Store a texture in a signed normalized 8-bit format.
2430 */
2431 static GLboolean
_mesa_texstore_snorm8(TEXSTORE_PARAMS)2432 _mesa_texstore_snorm8(TEXSTORE_PARAMS)
2433 {
2434 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2435
2436 ASSERT(dstFormat == MESA_FORMAT_SIGNED_A8 ||
2437 dstFormat == MESA_FORMAT_SIGNED_L8 ||
2438 dstFormat == MESA_FORMAT_SIGNED_I8 ||
2439 dstFormat == MESA_FORMAT_SIGNED_R8);
2440 ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
2441
2442 if (!ctx->_ImageTransferState &&
2443 !srcPacking->SwapBytes &&
2444 baseInternalFormat == srcFormat &&
2445 srcType == GL_BYTE) {
2446 /* simple memcpy path */
2447 memcpy_texture(ctx, dims,
2448 dstFormat,
2449 dstRowStride, dstSlices,
2450 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2451 srcAddr, srcPacking);
2452 }
2453 else {
2454 /* general path */
2455 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2456 baseInternalFormat,
2457 baseFormat,
2458 srcWidth, srcHeight, srcDepth,
2459 srcFormat, srcType, srcAddr,
2460 srcPacking,
2461 ctx->_ImageTransferState);
2462 const GLfloat *src = tempImage;
2463 GLint img, row, col;
2464 if (!tempImage)
2465 return GL_FALSE;
2466 for (img = 0; img < srcDepth; img++) {
2467 GLbyte *dstRow = (GLbyte *) dstSlices[img];
2468 for (row = 0; row < srcHeight; row++) {
2469 for (col = 0; col < srcWidth; col++) {
2470 dstRow[col] = FLOAT_TO_BYTE_TEX(src[col]);
2471 }
2472 dstRow += dstRowStride;
2473 src += srcWidth;
2474 }
2475 }
2476 free((void *) tempImage);
2477 }
2478 return GL_TRUE;
2479 }
2480
2481
2482 /**
2483 * Store a texture in a signed normalized two-channel 16-bit format.
2484 */
2485 static GLboolean
_mesa_texstore_snorm88(TEXSTORE_PARAMS)2486 _mesa_texstore_snorm88(TEXSTORE_PARAMS)
2487 {
2488 const GLboolean littleEndian = _mesa_little_endian();
2489 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2490
2491 ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL88 ||
2492 dstFormat == MESA_FORMAT_SIGNED_RG88_REV);
2493 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2494
2495 if (!ctx->_ImageTransferState &&
2496 !srcPacking->SwapBytes &&
2497 baseInternalFormat == srcFormat &&
2498 srcType == GL_BYTE &&
2499 littleEndian) {
2500 /* simple memcpy path */
2501 memcpy_texture(ctx, dims,
2502 dstFormat,
2503 dstRowStride, dstSlices,
2504 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2505 srcAddr, srcPacking);
2506 }
2507 else {
2508 /* general path */
2509 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2510 baseInternalFormat,
2511 baseFormat,
2512 srcWidth, srcHeight, srcDepth,
2513 srcFormat, srcType, srcAddr,
2514 srcPacking,
2515 ctx->_ImageTransferState);
2516 const GLfloat *src = tempImage;
2517 GLint img, row, col;
2518 if (!tempImage)
2519 return GL_FALSE;
2520 for (img = 0; img < srcDepth; img++) {
2521 GLbyte *dstRow = (GLbyte *) dstSlices[img];
2522 for (row = 0; row < srcHeight; row++) {
2523 GLbyte *dst = dstRow;
2524 for (col = 0; col < srcWidth; col++) {
2525 dst[0] = FLOAT_TO_BYTE_TEX(src[0]);
2526 dst[1] = FLOAT_TO_BYTE_TEX(src[1]);
2527 src += 2;
2528 dst += 2;
2529 }
2530 dstRow += dstRowStride;
2531 }
2532 }
2533 free((void *) tempImage);
2534 }
2535 return GL_TRUE;
2536 }
2537
2538 /* Texstore for signed R16, A16, L16, I16. */
2539 static GLboolean
_mesa_texstore_snorm16(TEXSTORE_PARAMS)2540 _mesa_texstore_snorm16(TEXSTORE_PARAMS)
2541 {
2542 const GLboolean littleEndian = _mesa_little_endian();
2543 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2544
2545 ASSERT(dstFormat == MESA_FORMAT_SIGNED_R16 ||
2546 dstFormat == MESA_FORMAT_SIGNED_A16 ||
2547 dstFormat == MESA_FORMAT_SIGNED_L16 ||
2548 dstFormat == MESA_FORMAT_SIGNED_I16);
2549 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2550
2551 if (!ctx->_ImageTransferState &&
2552 !srcPacking->SwapBytes &&
2553 baseInternalFormat == srcFormat &&
2554 srcType == GL_SHORT &&
2555 littleEndian) {
2556 /* simple memcpy path */
2557 memcpy_texture(ctx, dims,
2558 dstFormat,
2559 dstRowStride, dstSlices,
2560 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2561 srcAddr, srcPacking);
2562 }
2563 else {
2564 /* general path */
2565 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2566 baseInternalFormat,
2567 baseFormat,
2568 srcWidth, srcHeight, srcDepth,
2569 srcFormat, srcType, srcAddr,
2570 srcPacking,
2571 ctx->_ImageTransferState);
2572 const GLfloat *src = tempImage;
2573 GLint img, row, col;
2574 if (!tempImage)
2575 return GL_FALSE;
2576 for (img = 0; img < srcDepth; img++) {
2577 GLubyte *dstRow = dstSlices[img];
2578 for (row = 0; row < srcHeight; row++) {
2579 GLshort *dstUS = (GLshort *) dstRow;
2580 for (col = 0; col < srcWidth; col++) {
2581 GLushort r;
2582
2583 UNCLAMPED_FLOAT_TO_SHORT(r, src[0]);
2584 dstUS[col] = r;
2585 src += 1;
2586 }
2587 dstRow += dstRowStride;
2588 }
2589 }
2590 free((void *) tempImage);
2591 }
2592 return GL_TRUE;
2593 }
2594
2595 /**
2596 * Do texstore for 2-channel, 16-bit/channel, signed normalized formats.
2597 */
2598 static GLboolean
_mesa_texstore_snorm1616(TEXSTORE_PARAMS)2599 _mesa_texstore_snorm1616(TEXSTORE_PARAMS)
2600 {
2601 const GLboolean littleEndian = _mesa_little_endian();
2602 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2603
2604 ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL1616 ||
2605 dstFormat == MESA_FORMAT_SIGNED_GR1616);
2606 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
2607
2608 if (!ctx->_ImageTransferState &&
2609 !srcPacking->SwapBytes &&
2610 baseInternalFormat == srcFormat &&
2611 srcType == GL_SHORT &&
2612 littleEndian) {
2613 /* simple memcpy path */
2614 memcpy_texture(ctx, dims,
2615 dstFormat,
2616 dstRowStride, dstSlices,
2617 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2618 srcAddr, srcPacking);
2619 }
2620 else {
2621 /* general path */
2622 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2623 baseInternalFormat,
2624 baseFormat,
2625 srcWidth, srcHeight, srcDepth,
2626 srcFormat, srcType, srcAddr,
2627 srcPacking,
2628 ctx->_ImageTransferState);
2629 const GLfloat *src = tempImage;
2630 GLint img, row, col;
2631 if (!tempImage)
2632 return GL_FALSE;
2633 for (img = 0; img < srcDepth; img++) {
2634 GLubyte *dstRow = dstSlices[img];
2635 for (row = 0; row < srcHeight; row++) {
2636 GLshort *dst = (GLshort *) dstRow;
2637 for (col = 0; col < srcWidth; col++) {
2638 GLushort l, a;
2639
2640 UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
2641 UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
2642 dst[0] = l;
2643 dst[1] = a;
2644 src += 2;
2645 dst += 2;
2646 }
2647 dstRow += dstRowStride;
2648 }
2649 }
2650 free((void *) tempImage);
2651 }
2652 return GL_TRUE;
2653 }
2654
2655 /**
2656 * Store a texture in MESA_FORMAT_SIGNED_RGBX8888.
2657 */
2658 static GLboolean
_mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)2659 _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)
2660 {
2661 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2662
2663 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888);
2664 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
2665
2666 {
2667 /* general path */
2668 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2669 baseInternalFormat,
2670 baseFormat,
2671 srcWidth, srcHeight, srcDepth,
2672 srcFormat, srcType, srcAddr,
2673 srcPacking,
2674 ctx->_ImageTransferState);
2675 const GLfloat *srcRow = tempImage;
2676 GLint img, row, col;
2677 if (!tempImage)
2678 return GL_FALSE;
2679 for (img = 0; img < srcDepth; img++) {
2680 GLbyte *dstRow = (GLbyte *) dstSlices[img];
2681 for (row = 0; row < srcHeight; row++) {
2682 GLbyte *dst = dstRow;
2683 for (col = 0; col < srcWidth; col++) {
2684 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2685 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
2686 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
2687 dst[0] = 127;
2688 srcRow += 3;
2689 dst += 4;
2690 }
2691 dstRow += dstRowStride;
2692 }
2693 }
2694 free((void *) tempImage);
2695 }
2696 return GL_TRUE;
2697 }
2698
2699
2700
2701 /**
2702 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or
2703 * MESA_FORMAT_SIGNED_RGBA8888_REV
2704 */
2705 static GLboolean
_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)2706 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
2707 {
2708 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2709
2710 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 ||
2711 dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV);
2712 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
2713
2714 if (!ctx->_ImageTransferState &&
2715 baseInternalFormat == GL_RGBA &&
2716 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
2717 srcPacking->SwapBytes)) {
2718 /* simple memcpy path */
2719 memcpy_texture(ctx, dims,
2720 dstFormat,
2721 dstRowStride, dstSlices,
2722 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2723 srcAddr, srcPacking);
2724 }
2725 else {
2726 /* general path */
2727 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2728 baseInternalFormat,
2729 baseFormat,
2730 srcWidth, srcHeight, srcDepth,
2731 srcFormat, srcType, srcAddr,
2732 srcPacking,
2733 ctx->_ImageTransferState);
2734 const GLfloat *srcRow = tempImage;
2735 GLint img, row, col;
2736 if (!tempImage)
2737 return GL_FALSE;
2738 for (img = 0; img < srcDepth; img++) {
2739 GLbyte *dstRow = (GLbyte *) dstSlices[img];
2740 for (row = 0; row < srcHeight; row++) {
2741 GLbyte *dst = dstRow;
2742 if (dstFormat == MESA_FORMAT_SIGNED_RGBA8888) {
2743 for (col = 0; col < srcWidth; col++) {
2744 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2745 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
2746 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
2747 dst[0] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
2748 srcRow += 4;
2749 dst += 4;
2750 }
2751 }
2752 else {
2753 for (col = 0; col < srcWidth; col++) {
2754 dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2755 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
2756 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
2757 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
2758 srcRow += 4;
2759 dst += 4;
2760 }
2761 }
2762 dstRow += dstRowStride;
2763 }
2764 }
2765 free((void *) tempImage);
2766 }
2767 return GL_TRUE;
2768 }
2769
2770
2771 /**
2772 * Store a combined depth/stencil texture image.
2773 */
2774 static GLboolean
_mesa_texstore_z24_s8(TEXSTORE_PARAMS)2775 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
2776 {
2777 const GLuint depthScale = 0xffffff;
2778 const GLint srcRowStride
2779 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
2780 GLint img, row;
2781
2782 ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
2783 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
2784 srcFormat == GL_DEPTH_COMPONENT ||
2785 srcFormat == GL_STENCIL_INDEX);
2786 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
2787
2788 if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f &&
2789 ctx->Pixel.DepthBias == 0.0f &&
2790 !srcPacking->SwapBytes) {
2791 /* simple path */
2792 memcpy_texture(ctx, dims,
2793 dstFormat,
2794 dstRowStride, dstSlices,
2795 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2796 srcAddr, srcPacking);
2797 }
2798 else if (srcFormat == GL_DEPTH_COMPONENT ||
2799 srcFormat == GL_STENCIL_INDEX) {
2800 GLuint *depth = (GLuint *) malloc(srcWidth * sizeof(GLuint));
2801 GLubyte *stencil = (GLubyte *) malloc(srcWidth * sizeof(GLubyte));
2802
2803 if (!depth || !stencil) {
2804 free(depth);
2805 free(stencil);
2806 return GL_FALSE;
2807 }
2808
2809 /* In case we only upload depth we need to preserve the stencil */
2810 for (img = 0; img < srcDepth; img++) {
2811 GLuint *dstRow = (GLuint *) dstSlices[img];
2812 const GLubyte *src
2813 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2814 srcWidth, srcHeight,
2815 srcFormat, srcType,
2816 img, 0, 0);
2817 for (row = 0; row < srcHeight; row++) {
2818 GLint i;
2819 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
2820
2821 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
2822 keepstencil = GL_TRUE;
2823 }
2824 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
2825 keepdepth = GL_TRUE;
2826 }
2827
2828 if (keepdepth == GL_FALSE)
2829 /* the 24 depth bits will be in the low position: */
2830 _mesa_unpack_depth_span(ctx, srcWidth,
2831 GL_UNSIGNED_INT, /* dst type */
2832 keepstencil ? depth : dstRow, /* dst addr */
2833 depthScale,
2834 srcType, src, srcPacking);
2835
2836 if (keepstencil == GL_FALSE)
2837 /* get the 8-bit stencil values */
2838 _mesa_unpack_stencil_span(ctx, srcWidth,
2839 GL_UNSIGNED_BYTE, /* dst type */
2840 stencil, /* dst addr */
2841 srcType, src, srcPacking,
2842 ctx->_ImageTransferState);
2843
2844 for (i = 0; i < srcWidth; i++) {
2845 if (keepstencil)
2846 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
2847 else
2848 dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
2849 }
2850
2851 src += srcRowStride;
2852 dstRow += dstRowStride / sizeof(GLuint);
2853 }
2854 }
2855
2856 free(depth);
2857 free(stencil);
2858 }
2859 return GL_TRUE;
2860 }
2861
2862
2863 /**
2864 * Store a combined depth/stencil texture image.
2865 */
2866 static GLboolean
_mesa_texstore_s8_z24(TEXSTORE_PARAMS)2867 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
2868 {
2869 const GLuint depthScale = 0xffffff;
2870 const GLint srcRowStride
2871 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
2872 GLint img, row;
2873 GLuint *depth;
2874 GLubyte *stencil;
2875
2876 ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
2877 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
2878 srcFormat == GL_DEPTH_COMPONENT ||
2879 srcFormat == GL_STENCIL_INDEX);
2880 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
2881 srcType == GL_UNSIGNED_INT_24_8_EXT);
2882
2883 depth = (GLuint *) malloc(srcWidth * sizeof(GLuint));
2884 stencil = (GLubyte *) malloc(srcWidth * sizeof(GLubyte));
2885
2886 if (!depth || !stencil) {
2887 free(depth);
2888 free(stencil);
2889 return GL_FALSE;
2890 }
2891
2892 for (img = 0; img < srcDepth; img++) {
2893 GLuint *dstRow = (GLuint *) dstSlices[img];
2894 const GLubyte *src
2895 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2896 srcWidth, srcHeight,
2897 srcFormat, srcType,
2898 img, 0, 0);
2899 for (row = 0; row < srcHeight; row++) {
2900 GLint i;
2901 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
2902
2903 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
2904 keepstencil = GL_TRUE;
2905 }
2906 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
2907 keepdepth = GL_TRUE;
2908 }
2909
2910 if (keepdepth == GL_FALSE)
2911 /* the 24 depth bits will be in the low position: */
2912 _mesa_unpack_depth_span(ctx, srcWidth,
2913 GL_UNSIGNED_INT, /* dst type */
2914 keepstencil ? depth : dstRow, /* dst addr */
2915 depthScale,
2916 srcType, src, srcPacking);
2917
2918 if (keepstencil == GL_FALSE)
2919 /* get the 8-bit stencil values */
2920 _mesa_unpack_stencil_span(ctx, srcWidth,
2921 GL_UNSIGNED_BYTE, /* dst type */
2922 stencil, /* dst addr */
2923 srcType, src, srcPacking,
2924 ctx->_ImageTransferState);
2925
2926 /* merge stencil values into depth values */
2927 for (i = 0; i < srcWidth; i++) {
2928 if (keepstencil)
2929 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
2930 else
2931 dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
2932
2933 }
2934 src += srcRowStride;
2935 dstRow += dstRowStride / sizeof(GLuint);
2936 }
2937 }
2938
2939 free(depth);
2940 free(stencil);
2941
2942 return GL_TRUE;
2943 }
2944
2945
2946 /**
2947 * Store simple 8-bit/value stencil texture data.
2948 */
2949 static GLboolean
_mesa_texstore_s8(TEXSTORE_PARAMS)2950 _mesa_texstore_s8(TEXSTORE_PARAMS)
2951 {
2952 ASSERT(dstFormat == MESA_FORMAT_S8);
2953 ASSERT(srcFormat == GL_STENCIL_INDEX);
2954
2955 if (!ctx->_ImageTransferState &&
2956 !srcPacking->SwapBytes &&
2957 baseInternalFormat == srcFormat &&
2958 srcType == GL_UNSIGNED_BYTE) {
2959 /* simple memcpy path */
2960 memcpy_texture(ctx, dims,
2961 dstFormat,
2962 dstRowStride, dstSlices,
2963 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2964 srcAddr, srcPacking);
2965 }
2966 else {
2967 const GLint srcRowStride
2968 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
2969 GLint img, row;
2970 GLubyte *stencil = (GLubyte *) malloc(srcWidth * sizeof(GLubyte));
2971
2972 if (!stencil)
2973 return GL_FALSE;
2974
2975 for (img = 0; img < srcDepth; img++) {
2976 GLubyte *dstRow = dstSlices[img];
2977 const GLubyte *src
2978 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2979 srcWidth, srcHeight,
2980 srcFormat, srcType,
2981 img, 0, 0);
2982 for (row = 0; row < srcHeight; row++) {
2983 GLint i;
2984
2985 /* get the 8-bit stencil values */
2986 _mesa_unpack_stencil_span(ctx, srcWidth,
2987 GL_UNSIGNED_BYTE, /* dst type */
2988 stencil, /* dst addr */
2989 srcType, src, srcPacking,
2990 ctx->_ImageTransferState);
2991 /* merge stencil values into depth values */
2992 for (i = 0; i < srcWidth; i++)
2993 dstRow[i] = stencil[i];
2994
2995 src += srcRowStride;
2996 dstRow += dstRowStride / sizeof(GLubyte);
2997 }
2998 }
2999
3000 free(stencil);
3001 }
3002
3003 return GL_TRUE;
3004 }
3005
3006
3007 /**
3008 * Store an image in any of the formats:
3009 * _mesa_texformat_rgba_float32
3010 * _mesa_texformat_rgb_float32
3011 * _mesa_texformat_alpha_float32
3012 * _mesa_texformat_luminance_float32
3013 * _mesa_texformat_luminance_alpha_float32
3014 * _mesa_texformat_intensity_float32
3015 */
3016 static GLboolean
_mesa_texstore_rgba_float32(TEXSTORE_PARAMS)3017 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
3018 {
3019 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3020 const GLint components = _mesa_components_in_format(baseFormat);
3021
3022 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
3023 dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
3024 dstFormat == MESA_FORMAT_ALPHA_FLOAT32 ||
3025 dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 ||
3026 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 ||
3027 dstFormat == MESA_FORMAT_INTENSITY_FLOAT32 ||
3028 dstFormat == MESA_FORMAT_R_FLOAT32 ||
3029 dstFormat == MESA_FORMAT_RG_FLOAT32);
3030 ASSERT(baseInternalFormat == GL_RGBA ||
3031 baseInternalFormat == GL_RGB ||
3032 baseInternalFormat == GL_ALPHA ||
3033 baseInternalFormat == GL_LUMINANCE ||
3034 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3035 baseInternalFormat == GL_INTENSITY ||
3036 baseInternalFormat == GL_RED ||
3037 baseInternalFormat == GL_RG);
3038 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLfloat));
3039
3040 if (!ctx->_ImageTransferState &&
3041 !srcPacking->SwapBytes &&
3042 baseInternalFormat == srcFormat &&
3043 baseInternalFormat == baseFormat &&
3044 srcType == GL_FLOAT) {
3045 /* simple memcpy path */
3046 memcpy_texture(ctx, dims,
3047 dstFormat,
3048 dstRowStride, dstSlices,
3049 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3050 srcAddr, srcPacking);
3051 }
3052 else {
3053 /* general path */
3054 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3055 baseInternalFormat,
3056 baseFormat,
3057 srcWidth, srcHeight, srcDepth,
3058 srcFormat, srcType, srcAddr,
3059 srcPacking,
3060 ctx->_ImageTransferState);
3061 const GLfloat *srcRow = tempImage;
3062 GLint bytesPerRow;
3063 GLint img, row;
3064 if (!tempImage)
3065 return GL_FALSE;
3066 bytesPerRow = srcWidth * components * sizeof(GLfloat);
3067 for (img = 0; img < srcDepth; img++) {
3068 GLubyte *dstRow = dstSlices[img];
3069 for (row = 0; row < srcHeight; row++) {
3070 memcpy(dstRow, srcRow, bytesPerRow);
3071 dstRow += dstRowStride;
3072 srcRow += srcWidth * components;
3073 }
3074 }
3075
3076 free((void *) tempImage);
3077 }
3078 return GL_TRUE;
3079 }
3080
3081
3082
3083 /**
3084 * As above, but store 16-bit floats.
3085 */
3086 static GLboolean
_mesa_texstore_rgba_float16(TEXSTORE_PARAMS)3087 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
3088 {
3089 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3090 const GLint components = _mesa_components_in_format(baseFormat);
3091
3092 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
3093 dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
3094 dstFormat == MESA_FORMAT_ALPHA_FLOAT16 ||
3095 dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 ||
3096 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 ||
3097 dstFormat == MESA_FORMAT_INTENSITY_FLOAT16 ||
3098 dstFormat == MESA_FORMAT_R_FLOAT16 ||
3099 dstFormat == MESA_FORMAT_RG_FLOAT16);
3100 ASSERT(baseInternalFormat == GL_RGBA ||
3101 baseInternalFormat == GL_RGB ||
3102 baseInternalFormat == GL_ALPHA ||
3103 baseInternalFormat == GL_LUMINANCE ||
3104 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3105 baseInternalFormat == GL_INTENSITY ||
3106 baseInternalFormat == GL_RED ||
3107 baseInternalFormat == GL_RG);
3108 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLhalfARB));
3109
3110 if (!ctx->_ImageTransferState &&
3111 !srcPacking->SwapBytes &&
3112 baseInternalFormat == srcFormat &&
3113 baseInternalFormat == baseFormat &&
3114 srcType == GL_HALF_FLOAT_ARB) {
3115 /* simple memcpy path */
3116 memcpy_texture(ctx, dims,
3117 dstFormat,
3118 dstRowStride, dstSlices,
3119 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3120 srcAddr, srcPacking);
3121 }
3122 else {
3123 /* general path */
3124 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3125 baseInternalFormat,
3126 baseFormat,
3127 srcWidth, srcHeight, srcDepth,
3128 srcFormat, srcType, srcAddr,
3129 srcPacking,
3130 ctx->_ImageTransferState);
3131 const GLfloat *src = tempImage;
3132 GLint img, row;
3133 if (!tempImage)
3134 return GL_FALSE;
3135 for (img = 0; img < srcDepth; img++) {
3136 GLubyte *dstRow = dstSlices[img];
3137 for (row = 0; row < srcHeight; row++) {
3138 GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
3139 GLint i;
3140 for (i = 0; i < srcWidth * components; i++) {
3141 dstTexel[i] = _mesa_float_to_half(src[i]);
3142 }
3143 dstRow += dstRowStride;
3144 src += srcWidth * components;
3145 }
3146 }
3147
3148 free((void *) tempImage);
3149 }
3150 return GL_TRUE;
3151 }
3152
3153
3154 /* non-normalized, signed int8 */
3155 static GLboolean
_mesa_texstore_rgba_int8(TEXSTORE_PARAMS)3156 _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
3157 {
3158 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3159 const GLint components = _mesa_components_in_format(baseFormat);
3160
3161 ASSERT(dstFormat == MESA_FORMAT_R_INT8 ||
3162 dstFormat == MESA_FORMAT_RG_INT8 ||
3163 dstFormat == MESA_FORMAT_RGB_INT8 ||
3164 dstFormat == MESA_FORMAT_RGBA_INT8 ||
3165 dstFormat == MESA_FORMAT_ALPHA_INT8 ||
3166 dstFormat == MESA_FORMAT_INTENSITY_INT8 ||
3167 dstFormat == MESA_FORMAT_LUMINANCE_INT8 ||
3168 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8);
3169 ASSERT(baseInternalFormat == GL_RGBA ||
3170 baseInternalFormat == GL_RGB ||
3171 baseInternalFormat == GL_RG ||
3172 baseInternalFormat == GL_RED ||
3173 baseInternalFormat == GL_ALPHA ||
3174 baseInternalFormat == GL_LUMINANCE ||
3175 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3176 baseInternalFormat == GL_INTENSITY);
3177 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLbyte));
3178
3179 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3180 * to integer formats.
3181 */
3182 if (!srcPacking->SwapBytes &&
3183 baseInternalFormat == srcFormat &&
3184 srcType == GL_BYTE) {
3185 /* simple memcpy path */
3186 memcpy_texture(ctx, dims,
3187 dstFormat,
3188 dstRowStride, dstSlices,
3189 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3190 srcAddr, srcPacking);
3191 }
3192 else {
3193 /* general path */
3194 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3195 baseInternalFormat,
3196 baseFormat,
3197 srcWidth, srcHeight, srcDepth,
3198 srcFormat, srcType,
3199 srcAddr,
3200 srcPacking);
3201 const GLuint *src = tempImage;
3202 GLint img, row;
3203 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3204 if (!tempImage)
3205 return GL_FALSE;
3206 for (img = 0; img < srcDepth; img++) {
3207 GLubyte *dstRow = dstSlices[img];
3208 for (row = 0; row < srcHeight; row++) {
3209 GLbyte *dstTexel = (GLbyte *) dstRow;
3210 GLint i;
3211 if (is_unsigned) {
3212 for (i = 0; i < srcWidth * components; i++) {
3213 dstTexel[i] = (GLbyte) MIN2(src[i], 0x7f);
3214 }
3215 } else {
3216 for (i = 0; i < srcWidth * components; i++) {
3217 dstTexel[i] = (GLbyte) CLAMP((GLint) src[i], -0x80, 0x7f);
3218 }
3219 }
3220 dstRow += dstRowStride;
3221 src += srcWidth * components;
3222 }
3223 }
3224
3225 free((void *) tempImage);
3226 }
3227 return GL_TRUE;
3228 }
3229
3230
3231 /* non-normalized, signed int16 */
3232 static GLboolean
_mesa_texstore_rgba_int16(TEXSTORE_PARAMS)3233 _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
3234 {
3235 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3236 const GLint components = _mesa_components_in_format(baseFormat);
3237
3238 ASSERT(dstFormat == MESA_FORMAT_R_INT16 ||
3239 dstFormat == MESA_FORMAT_RG_INT16 ||
3240 dstFormat == MESA_FORMAT_RGB_INT16 ||
3241 dstFormat == MESA_FORMAT_RGBA_INT16 ||
3242 dstFormat == MESA_FORMAT_ALPHA_INT16 ||
3243 dstFormat == MESA_FORMAT_LUMINANCE_INT16 ||
3244 dstFormat == MESA_FORMAT_INTENSITY_INT16 ||
3245 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16);
3246 ASSERT(baseInternalFormat == GL_RGBA ||
3247 baseInternalFormat == GL_RGB ||
3248 baseInternalFormat == GL_RG ||
3249 baseInternalFormat == GL_RED ||
3250 baseInternalFormat == GL_ALPHA ||
3251 baseInternalFormat == GL_LUMINANCE ||
3252 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3253 baseInternalFormat == GL_INTENSITY);
3254 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort));
3255
3256 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3257 * to integer formats.
3258 */
3259 if (!srcPacking->SwapBytes &&
3260 baseInternalFormat == srcFormat &&
3261 srcType == GL_SHORT) {
3262 /* simple memcpy path */
3263 memcpy_texture(ctx, dims,
3264 dstFormat,
3265 dstRowStride, dstSlices,
3266 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3267 srcAddr, srcPacking);
3268 }
3269 else {
3270 /* general path */
3271 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3272 baseInternalFormat,
3273 baseFormat,
3274 srcWidth, srcHeight, srcDepth,
3275 srcFormat, srcType,
3276 srcAddr,
3277 srcPacking);
3278 const GLuint *src = tempImage;
3279 GLint img, row;
3280 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3281 if (!tempImage)
3282 return GL_FALSE;
3283 for (img = 0; img < srcDepth; img++) {
3284 GLubyte *dstRow = dstSlices[img];
3285 for (row = 0; row < srcHeight; row++) {
3286 GLshort *dstTexel = (GLshort *) dstRow;
3287 GLint i;
3288 if (is_unsigned) {
3289 for (i = 0; i < srcWidth * components; i++) {
3290 dstTexel[i] = (GLshort) MIN2(src[i], 0x7fff);
3291 }
3292 } else {
3293 for (i = 0; i < srcWidth * components; i++) {
3294 dstTexel[i] = (GLshort)CLAMP((GLint) src[i], -0x8000, 0x7fff);
3295 }
3296 }
3297 dstRow += dstRowStride;
3298 src += srcWidth * components;
3299 }
3300 }
3301
3302 free((void *) tempImage);
3303 }
3304 return GL_TRUE;
3305 }
3306
3307
3308 /* non-normalized, signed int32 */
3309 static GLboolean
_mesa_texstore_rgba_int32(TEXSTORE_PARAMS)3310 _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
3311 {
3312 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3313 const GLint components = _mesa_components_in_format(baseFormat);
3314
3315 ASSERT(dstFormat == MESA_FORMAT_R_INT32 ||
3316 dstFormat == MESA_FORMAT_RG_INT32 ||
3317 dstFormat == MESA_FORMAT_RGB_INT32 ||
3318 dstFormat == MESA_FORMAT_RGBA_INT32 ||
3319 dstFormat == MESA_FORMAT_ALPHA_INT32 ||
3320 dstFormat == MESA_FORMAT_INTENSITY_INT32 ||
3321 dstFormat == MESA_FORMAT_LUMINANCE_INT32 ||
3322 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32);
3323 ASSERT(baseInternalFormat == GL_RGBA ||
3324 baseInternalFormat == GL_RGB ||
3325 baseInternalFormat == GL_RG ||
3326 baseInternalFormat == GL_RED ||
3327 baseInternalFormat == GL_ALPHA ||
3328 baseInternalFormat == GL_LUMINANCE ||
3329 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3330 baseInternalFormat == GL_INTENSITY);
3331 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint));
3332
3333 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3334 * to integer formats.
3335 */
3336 if (!srcPacking->SwapBytes &&
3337 baseInternalFormat == srcFormat &&
3338 srcType == GL_INT) {
3339 /* simple memcpy path */
3340 memcpy_texture(ctx, dims,
3341 dstFormat,
3342 dstRowStride, dstSlices,
3343 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3344 srcAddr, srcPacking);
3345 }
3346 else {
3347 /* general path */
3348 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3349 baseInternalFormat,
3350 baseFormat,
3351 srcWidth, srcHeight, srcDepth,
3352 srcFormat, srcType,
3353 srcAddr,
3354 srcPacking);
3355 const GLuint *src = tempImage;
3356 GLint img, row;
3357 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3358 if (!tempImage)
3359 return GL_FALSE;
3360 for (img = 0; img < srcDepth; img++) {
3361 GLubyte *dstRow = dstSlices[img];
3362 for (row = 0; row < srcHeight; row++) {
3363 GLint *dstTexel = (GLint *) dstRow;
3364 GLint i;
3365 if (is_unsigned) {
3366 for (i = 0; i < srcWidth * components; i++) {
3367 dstTexel[i] = (GLint) MIN2(src[i], 0x7fffffff);
3368 }
3369 } else {
3370 for (i = 0; i < srcWidth * components; i++) {
3371 dstTexel[i] = (GLint) src[i];
3372 }
3373 }
3374 dstRow += dstRowStride;
3375 src += srcWidth * components;
3376 }
3377 }
3378
3379 free((void *) tempImage);
3380 }
3381 return GL_TRUE;
3382 }
3383
3384
3385 /* non-normalized, unsigned int8 */
3386 static GLboolean
_mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)3387 _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
3388 {
3389 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3390 const GLint components = _mesa_components_in_format(baseFormat);
3391
3392 ASSERT(dstFormat == MESA_FORMAT_R_UINT8 ||
3393 dstFormat == MESA_FORMAT_RG_UINT8 ||
3394 dstFormat == MESA_FORMAT_RGB_UINT8 ||
3395 dstFormat == MESA_FORMAT_RGBA_UINT8 ||
3396 dstFormat == MESA_FORMAT_ALPHA_UINT8 ||
3397 dstFormat == MESA_FORMAT_INTENSITY_UINT8 ||
3398 dstFormat == MESA_FORMAT_LUMINANCE_UINT8 ||
3399 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8);
3400 ASSERT(baseInternalFormat == GL_RGBA ||
3401 baseInternalFormat == GL_RGB ||
3402 baseInternalFormat == GL_RG ||
3403 baseInternalFormat == GL_RED ||
3404 baseInternalFormat == GL_ALPHA ||
3405 baseInternalFormat == GL_LUMINANCE ||
3406 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3407 baseInternalFormat == GL_INTENSITY);
3408 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte));
3409
3410 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3411 * to integer formats.
3412 */
3413 if (!srcPacking->SwapBytes &&
3414 baseInternalFormat == srcFormat &&
3415 srcType == GL_UNSIGNED_BYTE) {
3416 /* simple memcpy path */
3417 memcpy_texture(ctx, dims,
3418 dstFormat,
3419 dstRowStride, dstSlices,
3420 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3421 srcAddr, srcPacking);
3422 }
3423 else {
3424 /* general path */
3425 const GLuint *tempImage =
3426 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3427 srcWidth, srcHeight, srcDepth,
3428 srcFormat, srcType, srcAddr, srcPacking);
3429 const GLuint *src = tempImage;
3430 GLint img, row;
3431 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3432 if (!tempImage)
3433 return GL_FALSE;
3434 for (img = 0; img < srcDepth; img++) {
3435 GLubyte *dstRow = dstSlices[img];
3436 for (row = 0; row < srcHeight; row++) {
3437 GLubyte *dstTexel = (GLubyte *) dstRow;
3438 GLint i;
3439 if (is_unsigned) {
3440 for (i = 0; i < srcWidth * components; i++) {
3441 dstTexel[i] = (GLubyte) MIN2(src[i], 0xff);
3442 }
3443 } else {
3444 for (i = 0; i < srcWidth * components; i++) {
3445 dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff);
3446 }
3447 }
3448 dstRow += dstRowStride;
3449 src += srcWidth * components;
3450 }
3451 }
3452
3453 free((void *) tempImage);
3454 }
3455 return GL_TRUE;
3456 }
3457
3458
3459 /* non-normalized, unsigned int16 */
3460 static GLboolean
_mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)3461 _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
3462 {
3463 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3464 const GLint components = _mesa_components_in_format(baseFormat);
3465
3466 ASSERT(dstFormat == MESA_FORMAT_R_UINT16 ||
3467 dstFormat == MESA_FORMAT_RG_UINT16 ||
3468 dstFormat == MESA_FORMAT_RGB_UINT16 ||
3469 dstFormat == MESA_FORMAT_RGBA_UINT16 ||
3470 dstFormat == MESA_FORMAT_ALPHA_UINT16 ||
3471 dstFormat == MESA_FORMAT_INTENSITY_UINT16 ||
3472 dstFormat == MESA_FORMAT_LUMINANCE_UINT16 ||
3473 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16);
3474 ASSERT(baseInternalFormat == GL_RGBA ||
3475 baseInternalFormat == GL_RGB ||
3476 baseInternalFormat == GL_RG ||
3477 baseInternalFormat == GL_RED ||
3478 baseInternalFormat == GL_ALPHA ||
3479 baseInternalFormat == GL_LUMINANCE ||
3480 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3481 baseInternalFormat == GL_INTENSITY);
3482 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort));
3483
3484 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3485 * to integer formats.
3486 */
3487 if (!srcPacking->SwapBytes &&
3488 baseInternalFormat == srcFormat &&
3489 srcType == GL_UNSIGNED_SHORT) {
3490 /* simple memcpy path */
3491 memcpy_texture(ctx, dims,
3492 dstFormat,
3493 dstRowStride, dstSlices,
3494 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3495 srcAddr, srcPacking);
3496 }
3497 else {
3498 /* general path */
3499 const GLuint *tempImage =
3500 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3501 srcWidth, srcHeight, srcDepth,
3502 srcFormat, srcType, srcAddr, srcPacking);
3503 const GLuint *src = tempImage;
3504 GLint img, row;
3505 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3506 if (!tempImage)
3507 return GL_FALSE;
3508 for (img = 0; img < srcDepth; img++) {
3509 GLubyte *dstRow = dstSlices[img];
3510 for (row = 0; row < srcHeight; row++) {
3511 GLushort *dstTexel = (GLushort *) dstRow;
3512 GLint i;
3513 if (is_unsigned) {
3514 for (i = 0; i < srcWidth * components; i++) {
3515 dstTexel[i] = (GLushort) MIN2(src[i], 0xffff);
3516 }
3517 } else {
3518 for (i = 0; i < srcWidth * components; i++) {
3519 dstTexel[i] = (GLushort) CLAMP((GLint) src[i], 0, 0xffff);
3520 }
3521 }
3522 dstRow += dstRowStride;
3523 src += srcWidth * components;
3524 }
3525 }
3526
3527 free((void *) tempImage);
3528 }
3529 return GL_TRUE;
3530 }
3531
3532
3533 /* non-normalized, unsigned int32 */
3534 static GLboolean
_mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)3535 _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
3536 {
3537 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3538 const GLint components = _mesa_components_in_format(baseFormat);
3539
3540 ASSERT(dstFormat == MESA_FORMAT_R_UINT32 ||
3541 dstFormat == MESA_FORMAT_RG_UINT32 ||
3542 dstFormat == MESA_FORMAT_RGB_UINT32 ||
3543 dstFormat == MESA_FORMAT_RGBA_UINT32 ||
3544 dstFormat == MESA_FORMAT_ALPHA_UINT32 ||
3545 dstFormat == MESA_FORMAT_INTENSITY_UINT32 ||
3546 dstFormat == MESA_FORMAT_LUMINANCE_UINT32 ||
3547 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32);
3548 ASSERT(baseInternalFormat == GL_RGBA ||
3549 baseInternalFormat == GL_RGB ||
3550 baseInternalFormat == GL_RG ||
3551 baseInternalFormat == GL_RED ||
3552 baseInternalFormat == GL_ALPHA ||
3553 baseInternalFormat == GL_LUMINANCE ||
3554 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3555 baseInternalFormat == GL_INTENSITY);
3556 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint));
3557
3558 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3559 * to integer formats.
3560 */
3561 if (!srcPacking->SwapBytes &&
3562 baseInternalFormat == srcFormat &&
3563 srcType == GL_UNSIGNED_INT) {
3564 /* simple memcpy path */
3565 memcpy_texture(ctx, dims,
3566 dstFormat,
3567 dstRowStride, dstSlices,
3568 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3569 srcAddr, srcPacking);
3570 }
3571 else {
3572 /* general path */
3573 const GLuint *tempImage =
3574 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3575 srcWidth, srcHeight, srcDepth,
3576 srcFormat, srcType, srcAddr, srcPacking);
3577 const GLuint *src = tempImage;
3578 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3579 GLint img, row;
3580 if (!tempImage)
3581 return GL_FALSE;
3582 for (img = 0; img < srcDepth; img++) {
3583 GLubyte *dstRow = dstSlices[img];
3584 for (row = 0; row < srcHeight; row++) {
3585 GLuint *dstTexel = (GLuint *) dstRow;
3586 GLint i;
3587 if (is_unsigned) {
3588 for (i = 0; i < srcWidth * components; i++) {
3589 dstTexel[i] = src[i];
3590 }
3591 } else {
3592 for (i = 0; i < srcWidth * components; i++) {
3593 dstTexel[i] = MAX2((GLint) src[i], 0);
3594 }
3595 }
3596 dstRow += dstRowStride;
3597 src += srcWidth * components;
3598 }
3599 }
3600
3601 free((void *) tempImage);
3602 }
3603 return GL_TRUE;
3604 }
3605
3606
3607
3608
3609 #if FEATURE_EXT_texture_sRGB
3610 static GLboolean
_mesa_texstore_srgb8(TEXSTORE_PARAMS)3611 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
3612 {
3613 gl_format newDstFormat;
3614 GLboolean k;
3615
3616 ASSERT(dstFormat == MESA_FORMAT_SRGB8);
3617
3618 /* reuse normal rgb texstore code */
3619 newDstFormat = MESA_FORMAT_RGB888;
3620
3621 k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
3622 newDstFormat,
3623 dstRowStride, dstSlices,
3624 srcWidth, srcHeight, srcDepth,
3625 srcFormat, srcType,
3626 srcAddr, srcPacking);
3627 return k;
3628 }
3629
3630
3631 static GLboolean
_mesa_texstore_srgba8(TEXSTORE_PARAMS)3632 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
3633 {
3634 gl_format newDstFormat;
3635 GLboolean k;
3636
3637 ASSERT(dstFormat == MESA_FORMAT_SRGBA8);
3638
3639 /* reuse normal rgba texstore code */
3640 newDstFormat = MESA_FORMAT_RGBA8888;
3641 k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
3642 newDstFormat,
3643 dstRowStride, dstSlices,
3644 srcWidth, srcHeight, srcDepth,
3645 srcFormat, srcType,
3646 srcAddr, srcPacking);
3647 return k;
3648 }
3649
3650
3651 static GLboolean
_mesa_texstore_sargb8(TEXSTORE_PARAMS)3652 _mesa_texstore_sargb8(TEXSTORE_PARAMS)
3653 {
3654 gl_format newDstFormat;
3655 GLboolean k;
3656
3657 ASSERT(dstFormat == MESA_FORMAT_SARGB8);
3658
3659 /* reuse normal rgba texstore code */
3660 newDstFormat = MESA_FORMAT_ARGB8888;
3661
3662 k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
3663 newDstFormat,
3664 dstRowStride, dstSlices,
3665 srcWidth, srcHeight, srcDepth,
3666 srcFormat, srcType,
3667 srcAddr, srcPacking);
3668 return k;
3669 }
3670
3671
3672 static GLboolean
_mesa_texstore_sl8(TEXSTORE_PARAMS)3673 _mesa_texstore_sl8(TEXSTORE_PARAMS)
3674 {
3675 gl_format newDstFormat;
3676 GLboolean k;
3677
3678 ASSERT(dstFormat == MESA_FORMAT_SL8);
3679
3680 newDstFormat = MESA_FORMAT_L8;
3681
3682 /* _mesa_textore_a8 handles luminance8 too */
3683 k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat,
3684 newDstFormat,
3685 dstRowStride, dstSlices,
3686 srcWidth, srcHeight, srcDepth,
3687 srcFormat, srcType,
3688 srcAddr, srcPacking);
3689 return k;
3690 }
3691
3692
3693 static GLboolean
_mesa_texstore_sla8(TEXSTORE_PARAMS)3694 _mesa_texstore_sla8(TEXSTORE_PARAMS)
3695 {
3696 gl_format newDstFormat;
3697 GLboolean k;
3698
3699 ASSERT(dstFormat == MESA_FORMAT_SLA8);
3700
3701 /* reuse normal luminance/alpha texstore code */
3702 newDstFormat = MESA_FORMAT_AL88;
3703
3704 k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
3705 newDstFormat,
3706 dstRowStride, dstSlices,
3707 srcWidth, srcHeight, srcDepth,
3708 srcFormat, srcType,
3709 srcAddr, srcPacking);
3710 return k;
3711 }
3712
3713 #else
3714
3715 /* these are used only in texstore_funcs[] below */
3716 #define _mesa_texstore_srgb8 NULL
3717 #define _mesa_texstore_srgba8 NULL
3718 #define _mesa_texstore_sargb8 NULL
3719 #define _mesa_texstore_sl8 NULL
3720 #define _mesa_texstore_sla8 NULL
3721
3722 #endif /* FEATURE_EXT_texture_sRGB */
3723
3724 static GLboolean
_mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)3725 _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
3726 {
3727 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3728
3729 ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT);
3730 ASSERT(baseInternalFormat == GL_RGB);
3731
3732 if (!ctx->_ImageTransferState &&
3733 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
3734 srcPacking->SwapBytes)) {
3735 /* simple memcpy path */
3736 memcpy_texture(ctx, dims,
3737 dstFormat,
3738 dstRowStride, dstSlices,
3739 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3740 srcAddr, srcPacking);
3741 }
3742 else {
3743 /* general path */
3744 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3745 baseInternalFormat,
3746 baseFormat,
3747 srcWidth, srcHeight, srcDepth,
3748 srcFormat, srcType, srcAddr,
3749 srcPacking,
3750 ctx->_ImageTransferState);
3751 const GLfloat *srcRow = tempImage;
3752 GLint img, row, col;
3753 if (!tempImage)
3754 return GL_FALSE;
3755 for (img = 0; img < srcDepth; img++) {
3756 GLubyte *dstRow = dstSlices[img];
3757 for (row = 0; row < srcHeight; row++) {
3758 GLuint *dstUI = (GLuint*)dstRow;
3759 for (col = 0; col < srcWidth; col++) {
3760 dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]);
3761 }
3762 dstRow += dstRowStride;
3763 srcRow += srcWidth * 3;
3764 }
3765 }
3766
3767 free((void *) tempImage);
3768 }
3769 return GL_TRUE;
3770 }
3771
3772 static GLboolean
_mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)3773 _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)
3774 {
3775 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3776
3777 ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT);
3778 ASSERT(baseInternalFormat == GL_RGB);
3779
3780 if (!ctx->_ImageTransferState &&
3781 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
3782 srcPacking->SwapBytes)) {
3783 /* simple memcpy path */
3784 memcpy_texture(ctx, dims,
3785 dstFormat,
3786 dstRowStride, dstSlices,
3787 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3788 srcAddr, srcPacking);
3789 }
3790 else {
3791 /* general path */
3792 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3793 baseInternalFormat,
3794 baseFormat,
3795 srcWidth, srcHeight, srcDepth,
3796 srcFormat, srcType, srcAddr,
3797 srcPacking,
3798 ctx->_ImageTransferState);
3799 const GLfloat *srcRow = tempImage;
3800 GLint img, row, col;
3801 if (!tempImage)
3802 return GL_FALSE;
3803 for (img = 0; img < srcDepth; img++) {
3804 GLubyte *dstRow = dstSlices[img];
3805 for (row = 0; row < srcHeight; row++) {
3806 GLuint *dstUI = (GLuint*)dstRow;
3807 for (col = 0; col < srcWidth; col++) {
3808 dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]);
3809 }
3810 dstRow += dstRowStride;
3811 srcRow += srcWidth * 3;
3812 }
3813 }
3814
3815 free((void *) tempImage);
3816 }
3817 return GL_TRUE;
3818 }
3819
3820
3821 static GLboolean
_mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)3822 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
3823 {
3824 ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8);
3825 ASSERT(srcFormat == GL_DEPTH_STENCIL ||
3826 srcFormat == GL_DEPTH_COMPONENT ||
3827 srcFormat == GL_STENCIL_INDEX);
3828 ASSERT(srcFormat != GL_DEPTH_STENCIL ||
3829 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
3830
3831 if (srcFormat == GL_DEPTH_STENCIL &&
3832 ctx->Pixel.DepthScale == 1.0f &&
3833 ctx->Pixel.DepthBias == 0.0f &&
3834 !srcPacking->SwapBytes) {
3835 /* simple path */
3836 memcpy_texture(ctx, dims,
3837 dstFormat,
3838 dstRowStride, dstSlices,
3839 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3840 srcAddr, srcPacking);
3841 }
3842 else if (srcFormat == GL_DEPTH_COMPONENT ||
3843 srcFormat == GL_STENCIL_INDEX) {
3844 GLint img, row;
3845 const GLint srcRowStride
3846 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
3847 / sizeof(uint64_t);
3848
3849 /* In case we only upload depth we need to preserve the stencil */
3850 for (img = 0; img < srcDepth; img++) {
3851 uint64_t *dstRow = (uint64_t *) dstSlices[img];
3852 const uint64_t *src
3853 = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
3854 srcWidth, srcHeight,
3855 srcFormat, srcType,
3856 img, 0, 0);
3857 for (row = 0; row < srcHeight; row++) {
3858 /* The unpack functions with:
3859 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
3860 * only write their own dword, so the other dword (stencil
3861 * or depth) is preserved. */
3862 if (srcFormat != GL_STENCIL_INDEX)
3863 _mesa_unpack_depth_span(ctx, srcWidth,
3864 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
3865 dstRow, /* dst addr */
3866 ~0U, srcType, src, srcPacking);
3867
3868 if (srcFormat != GL_DEPTH_COMPONENT)
3869 _mesa_unpack_stencil_span(ctx, srcWidth,
3870 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
3871 dstRow, /* dst addr */
3872 srcType, src, srcPacking,
3873 ctx->_ImageTransferState);
3874
3875 src += srcRowStride;
3876 dstRow += dstRowStride / sizeof(uint64_t);
3877 }
3878 }
3879 }
3880 return GL_TRUE;
3881 }
3882
3883 static GLboolean
_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)3884 _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
3885 {
3886 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3887
3888 ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT);
3889 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
3890
3891 if (baseInternalFormat == GL_RGBA &&
3892 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
3893 srcPacking->SwapBytes)) {
3894 /* simple memcpy path */
3895 memcpy_texture(ctx, dims,
3896 dstFormat,
3897 dstRowStride, dstSlices,
3898 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3899 srcAddr, srcPacking);
3900 }
3901 else {
3902 /* general path */
3903 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3904 baseInternalFormat,
3905 baseFormat,
3906 srcWidth, srcHeight,
3907 srcDepth, srcFormat,
3908 srcType, srcAddr,
3909 srcPacking);
3910 const GLuint *src = tempImage;
3911 GLint img, row, col;
3912 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3913 if (!tempImage)
3914 return GL_FALSE;
3915 for (img = 0; img < srcDepth; img++) {
3916 GLubyte *dstRow = dstSlices[img];
3917
3918 for (row = 0; row < srcHeight; row++) {
3919 GLuint *dstUI = (GLuint *) dstRow;
3920 if (is_unsigned) {
3921 for (col = 0; col < srcWidth; col++) {
3922 GLushort a,r,g,b;
3923 r = MIN2(src[RCOMP], 0x3ff);
3924 g = MIN2(src[GCOMP], 0x3ff);
3925 b = MIN2(src[BCOMP], 0x3ff);
3926 a = MIN2(src[ACOMP], 0x003);
3927 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
3928 src += 4;
3929 }
3930 } else {
3931 for (col = 0; col < srcWidth; col++) {
3932 GLushort a,r,g,b;
3933 r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
3934 g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
3935 b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
3936 a = CLAMP((GLint) src[ACOMP], 0, 0x003);
3937 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
3938 src += 4;
3939 }
3940 }
3941 dstRow += dstRowStride;
3942 }
3943 }
3944 free((void *) tempImage);
3945 }
3946 return GL_TRUE;
3947 }
3948
3949 static GLboolean
_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)3950 _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
3951 {
3952 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3953
3954 ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT);
3955 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
3956
3957 if (baseInternalFormat == GL_RGBA &&
3958 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
3959 srcPacking->SwapBytes)) {
3960 /* simple memcpy path */
3961 memcpy_texture(ctx, dims,
3962 dstFormat,
3963 dstRowStride, dstSlices,
3964 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3965 srcAddr, srcPacking);
3966 }
3967 else {
3968 /* general path */
3969 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3970 baseInternalFormat,
3971 baseFormat,
3972 srcWidth, srcHeight,
3973 srcDepth, srcFormat,
3974 srcType, srcAddr,
3975 srcPacking);
3976 const GLuint *src = tempImage;
3977 GLint img, row, col;
3978 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3979 if (!tempImage)
3980 return GL_FALSE;
3981 for (img = 0; img < srcDepth; img++) {
3982 GLubyte *dstRow = dstSlices[img];
3983
3984 for (row = 0; row < srcHeight; row++) {
3985 GLuint *dstUI = (GLuint *) dstRow;
3986 if (is_unsigned) {
3987 for (col = 0; col < srcWidth; col++) {
3988 GLushort a,r,g,b;
3989 r = MIN2(src[RCOMP], 0x3ff);
3990 g = MIN2(src[GCOMP], 0x3ff);
3991 b = MIN2(src[BCOMP], 0x3ff);
3992 a = MIN2(src[ACOMP], 0x003);
3993 dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
3994 src += 4;
3995 }
3996 } else {
3997 for (col = 0; col < srcWidth; col++) {
3998 GLushort a,r,g,b;
3999 r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
4000 g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
4001 b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
4002 a = CLAMP((GLint) src[ACOMP], 0, 0x003);
4003 dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
4004 src += 4;
4005 }
4006 }
4007 dstRow += dstRowStride;
4008 }
4009 }
4010 free((void *) tempImage);
4011 }
4012 return GL_TRUE;
4013 }
4014
4015 static GLboolean
_mesa_texstore_null(TEXSTORE_PARAMS)4016 _mesa_texstore_null(TEXSTORE_PARAMS)
4017 {
4018 (void) ctx; (void) dims;
4019 (void) baseInternalFormat;
4020 (void) dstFormat;
4021 (void) dstRowStride; (void) dstSlices,
4022 (void) srcWidth; (void) srcHeight; (void) srcDepth;
4023 (void) srcFormat; (void) srcType;
4024 (void) srcAddr;
4025 (void) srcPacking;
4026
4027 /* should never happen */
4028 _mesa_problem(NULL, "_mesa_texstore_null() is called");
4029 return GL_FALSE;
4030 }
4031
4032
4033 /**
4034 * Return the StoreTexImageFunc pointer to store an image in the given format.
4035 */
4036 static StoreTexImageFunc
_mesa_get_texstore_func(gl_format format)4037 _mesa_get_texstore_func(gl_format format)
4038 {
4039 static StoreTexImageFunc table[MESA_FORMAT_COUNT];
4040 static GLboolean initialized = GL_FALSE;
4041
4042 if (!initialized) {
4043 table[MESA_FORMAT_NONE] = _mesa_texstore_null;
4044
4045 table[MESA_FORMAT_RGBA8888] = _mesa_texstore_rgba8888;
4046 table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888;
4047 table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888;
4048 table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888;
4049 table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888;
4050 table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888;
4051 table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888;
4052 table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888;
4053 table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888;
4054 table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888;
4055 table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565;
4056 table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565;
4057 table[MESA_FORMAT_ARGB4444] = _mesa_texstore_argb4444;
4058 table[MESA_FORMAT_ARGB4444_REV] = _mesa_texstore_argb4444;
4059 table[MESA_FORMAT_RGBA5551] = _mesa_texstore_rgba5551;
4060 table[MESA_FORMAT_ARGB1555] = _mesa_texstore_argb1555;
4061 table[MESA_FORMAT_ARGB1555_REV] = _mesa_texstore_argb1555;
4062 table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44;
4063 table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88;
4064 table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88;
4065 table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616;
4066 table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616;
4067 table[MESA_FORMAT_RGB332] = _mesa_texstore_rgb332;
4068 table[MESA_FORMAT_A8] = _mesa_texstore_unorm8;
4069 table[MESA_FORMAT_A16] = _mesa_texstore_unorm16;
4070 table[MESA_FORMAT_L8] = _mesa_texstore_unorm8;
4071 table[MESA_FORMAT_L16] = _mesa_texstore_unorm16;
4072 table[MESA_FORMAT_I8] = _mesa_texstore_unorm8;
4073 table[MESA_FORMAT_I16] = _mesa_texstore_unorm16;
4074 table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
4075 table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
4076 table[MESA_FORMAT_R8] = _mesa_texstore_unorm8;
4077 table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88;
4078 table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88;
4079 table[MESA_FORMAT_R16] = _mesa_texstore_unorm16;
4080 table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616;
4081 table[MESA_FORMAT_RG1616_REV] = _mesa_texstore_unorm1616;
4082 table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010;
4083 table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8;
4084 table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24;
4085 table[MESA_FORMAT_Z16] = _mesa_texstore_z16;
4086 table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24;
4087 table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8;
4088 table[MESA_FORMAT_Z32] = _mesa_texstore_z32;
4089 table[MESA_FORMAT_S8] = _mesa_texstore_s8;
4090 table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8;
4091 table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8;
4092 table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8;
4093 table[MESA_FORMAT_SL8] = _mesa_texstore_sl8;
4094 table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8;
4095 table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
4096 table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
4097 table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
4098 table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
4099 table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
4100 table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
4101 table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
4102 table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
4103 table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
4104 table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
4105 table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32;
4106 table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16;
4107 table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32;
4108 table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16;
4109 table[MESA_FORMAT_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
4110 table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
4111 table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32;
4112 table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16;
4113 table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
4114 table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
4115 table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32;
4116 table[MESA_FORMAT_INTENSITY_FLOAT16] = _mesa_texstore_rgba_float16;
4117 table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32;
4118 table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16;
4119 table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32;
4120 table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16;
4121 table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8;
4122 table[MESA_FORMAT_SIGNED_R8] = _mesa_texstore_snorm8;
4123 table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88;
4124 table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888;
4125 table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888;
4126 table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888;
4127 table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16;
4128 table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616;
4129 table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16;
4130 table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16;
4131 table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16;
4132 table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1;
4133 table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1;
4134 table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2;
4135 table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2;
4136 table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1;
4137 table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1;
4138 table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2;
4139 table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2;
4140 table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
4141 table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8;
4142 table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8;
4143 table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88;
4144 table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8;
4145 table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16;
4146 table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16;
4147 table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616;
4148 table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16;
4149 table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5;
4150 table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f;
4151 table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32;
4152 table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8;
4153
4154 table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
4155 table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
4156 table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
4157 table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8;
4158 table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16;
4159 table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32;
4160
4161 table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8;
4162 table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16;
4163 table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32;
4164 table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8;
4165 table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16;
4166 table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32;
4167
4168 table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8;
4169 table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16;
4170 table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32;
4171 table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8;
4172 table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16;
4173 table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32;
4174
4175 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
4176 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
4177 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
4178 table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8;
4179 table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16;
4180 table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32;
4181
4182 table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8;
4183 table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8;
4184 table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8;
4185 table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8;
4186 table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16;
4187 table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16;
4188 table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16;
4189 table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16;
4190 table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32;
4191 table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32;
4192 table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32;
4193 table[MESA_FORMAT_RGBA_INT32] = _mesa_texstore_rgba_int32;
4194
4195 table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8;
4196 table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8;
4197 table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8;
4198 table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8;
4199 table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16;
4200 table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16;
4201 table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16;
4202 table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16;
4203 table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32;
4204 table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32;
4205 table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32;
4206 table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32;
4207
4208 table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint;
4209 table[MESA_FORMAT_ABGR2101010_UINT] = _mesa_texstore_abgr2101010_uint;
4210 initialized = GL_TRUE;
4211 }
4212
4213 ASSERT(table[format]);
4214 return table[format];
4215 }
4216
4217
4218 /**
4219 * Store user data into texture memory.
4220 * Called via glTex[Sub]Image1/2/3D()
4221 */
4222 GLboolean
_mesa_texstore(TEXSTORE_PARAMS)4223 _mesa_texstore(TEXSTORE_PARAMS)
4224 {
4225 StoreTexImageFunc storeImage;
4226 GLboolean success;
4227
4228 storeImage = _mesa_get_texstore_func(dstFormat);
4229
4230 success = storeImage(ctx, dims, baseInternalFormat,
4231 dstFormat,
4232 dstRowStride, dstSlices,
4233 srcWidth, srcHeight, srcDepth,
4234 srcFormat, srcType, srcAddr, srcPacking);
4235 return success;
4236 }
4237
4238
4239 /**
4240 * Normally, we'll only _write_ texel data to a texture when we map it.
4241 * But if the user is providing depth or stencil values and the texture
4242 * image is a combined depth/stencil format, we'll actually read from
4243 * the texture buffer too (in order to insert the depth or stencil values.
4244 * \param userFormat the user-provided image format
4245 * \param texFormat the destination texture format
4246 */
4247 static GLbitfield
get_read_write_mode(GLenum userFormat,gl_format texFormat)4248 get_read_write_mode(GLenum userFormat, gl_format texFormat)
4249 {
4250 if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
4251 && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
4252 return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
4253 else
4254 return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
4255 }
4256
4257
4258 /**
4259 * Helper function for storing 1D, 2D, 3D whole and subimages into texture
4260 * memory.
4261 * The source of the image data may be user memory or a PBO. In the later
4262 * case, we'll map the PBO, copy from it, then unmap it.
4263 */
4264 static void
store_texsubimage(struct gl_context * ctx,struct gl_texture_image * texImage,GLint xoffset,GLint yoffset,GLint zoffset,GLint width,GLint height,GLint depth,GLenum format,GLenum type,const GLvoid * pixels,const struct gl_pixelstore_attrib * packing,const char * caller)4265 store_texsubimage(struct gl_context *ctx,
4266 struct gl_texture_image *texImage,
4267 GLint xoffset, GLint yoffset, GLint zoffset,
4268 GLint width, GLint height, GLint depth,
4269 GLenum format, GLenum type, const GLvoid *pixels,
4270 const struct gl_pixelstore_attrib *packing,
4271 const char *caller)
4272
4273 {
4274 const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat);
4275 const GLenum target = texImage->TexObject->Target;
4276 GLboolean success = GL_FALSE;
4277 GLuint dims, slice, numSlices = 1, sliceOffset = 0;
4278 GLint srcImageStride = 0;
4279 const GLubyte *src;
4280
4281 assert(xoffset + width <= texImage->Width);
4282 assert(yoffset + height <= texImage->Height);
4283 assert(zoffset + depth <= texImage->Depth);
4284
4285 switch (target) {
4286 case GL_TEXTURE_1D:
4287 dims = 1;
4288 break;
4289 case GL_TEXTURE_2D_ARRAY:
4290 case GL_TEXTURE_3D:
4291 dims = 3;
4292 break;
4293 default:
4294 dims = 2;
4295 }
4296
4297 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4298 src = (const GLubyte *)
4299 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
4300 format, type, pixels, packing, caller);
4301 if (!src)
4302 return;
4303
4304 /* compute slice info (and do some sanity checks) */
4305 switch (target) {
4306 case GL_TEXTURE_2D:
4307 case GL_TEXTURE_RECTANGLE:
4308 case GL_TEXTURE_CUBE_MAP:
4309 /* one image slice, nothing special needs to be done */
4310 break;
4311 case GL_TEXTURE_1D:
4312 assert(height == 1);
4313 assert(depth == 1);
4314 assert(yoffset == 0);
4315 assert(zoffset == 0);
4316 break;
4317 case GL_TEXTURE_1D_ARRAY:
4318 assert(depth == 1);
4319 assert(zoffset == 0);
4320 numSlices = height;
4321 sliceOffset = yoffset;
4322 height = 1;
4323 yoffset = 0;
4324 srcImageStride = _mesa_image_row_stride(packing, width, format, type);
4325 break;
4326 case GL_TEXTURE_2D_ARRAY:
4327 numSlices = depth;
4328 sliceOffset = zoffset;
4329 depth = 1;
4330 zoffset = 0;
4331 srcImageStride = _mesa_image_image_stride(packing, width, height,
4332 format, type);
4333 break;
4334 case GL_TEXTURE_3D:
4335 /* we'll store 3D images as a series of slices */
4336 numSlices = depth;
4337 sliceOffset = zoffset;
4338 srcImageStride = _mesa_image_image_stride(packing, width, height,
4339 format, type);
4340 break;
4341 default:
4342 _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
4343 return;
4344 }
4345
4346 assert(numSlices == 1 || srcImageStride != 0);
4347
4348 for (slice = 0; slice < numSlices; slice++) {
4349 GLubyte *dstMap;
4350 GLint dstRowStride;
4351
4352 ctx->Driver.MapTextureImage(ctx, texImage,
4353 slice + sliceOffset,
4354 xoffset, yoffset, width, height,
4355 mapMode, &dstMap, &dstRowStride);
4356 if (dstMap) {
4357 /* Note: we're only storing a 2D (or 1D) slice at a time but we need
4358 * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
4359 * used for 3D images.
4360 */
4361 success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
4362 texImage->TexFormat,
4363 dstRowStride,
4364 &dstMap,
4365 width, height, 1, /* w, h, d */
4366 format, type, src, packing);
4367
4368 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
4369 }
4370
4371 src += srcImageStride;
4372
4373 if (!success)
4374 break;
4375 }
4376
4377 if (!success)
4378 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
4379
4380 _mesa_unmap_teximage_pbo(ctx, packing);
4381 }
4382
4383
4384
4385 /**
4386 * Fallback code for ctx->Driver.TexImage().
4387 * Basically, allocate storage for the texture image, then copy the
4388 * user's image into it.
4389 */
4390 void
_mesa_store_teximage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLenum format,GLenum type,const GLvoid * pixels,const struct gl_pixelstore_attrib * packing)4391 _mesa_store_teximage(struct gl_context *ctx,
4392 GLuint dims,
4393 struct gl_texture_image *texImage,
4394 GLenum format, GLenum type, const GLvoid *pixels,
4395 const struct gl_pixelstore_attrib *packing)
4396 {
4397 assert(dims == 1 || dims == 2 || dims == 3);
4398
4399 if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
4400 return;
4401
4402 /* allocate storage for texture data */
4403 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
4404 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
4405 return;
4406 }
4407
4408 store_texsubimage(ctx, texImage,
4409 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth,
4410 format, type, pixels, packing, "glTexImage");
4411 }
4412
4413
4414 /*
4415 * Fallback for Driver.TexSubImage().
4416 */
4417 void
_mesa_store_texsubimage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLint xoffset,GLint yoffset,GLint zoffset,GLint width,GLint height,GLint depth,GLenum format,GLenum type,const void * pixels,const struct gl_pixelstore_attrib * packing)4418 _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims,
4419 struct gl_texture_image *texImage,
4420 GLint xoffset, GLint yoffset, GLint zoffset,
4421 GLint width, GLint height, GLint depth,
4422 GLenum format, GLenum type, const void *pixels,
4423 const struct gl_pixelstore_attrib *packing)
4424 {
4425 store_texsubimage(ctx, texImage,
4426 xoffset, yoffset, zoffset, width, height, depth,
4427 format, type, pixels, packing, "glTexSubImage");
4428 }
4429
4430
4431 /**
4432 * Fallback for Driver.CompressedTexImage()
4433 */
4434 void
_mesa_store_compressed_teximage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLsizei imageSize,const GLvoid * data)4435 _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
4436 struct gl_texture_image *texImage,
4437 GLsizei imageSize, const GLvoid *data)
4438 {
4439 /* only 2D compressed images are supported at this time */
4440 if (dims != 2) {
4441 _mesa_problem(ctx, "Unexpected glCompressedTexImage1D/3D call");
4442 return;
4443 }
4444
4445 /* This is pretty simple, because unlike the general texstore path we don't
4446 * have to worry about the usual image unpacking or image transfer
4447 * operations.
4448 */
4449 ASSERT(texImage);
4450 ASSERT(texImage->Width > 0);
4451 ASSERT(texImage->Height > 0);
4452 ASSERT(texImage->Depth == 1);
4453
4454 /* allocate storage for texture data */
4455 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
4456 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
4457 return;
4458 }
4459
4460 _mesa_store_compressed_texsubimage(ctx, dims, texImage,
4461 0, 0, 0,
4462 texImage->Width, texImage->Height, texImage->Depth,
4463 texImage->TexFormat,
4464 imageSize, data);
4465 }
4466
4467
4468 /**
4469 * Fallback for Driver.CompressedTexSubImage()
4470 */
4471 void
_mesa_store_compressed_texsubimage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data)4472 _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
4473 struct gl_texture_image *texImage,
4474 GLint xoffset, GLint yoffset, GLint zoffset,
4475 GLsizei width, GLsizei height, GLsizei depth,
4476 GLenum format,
4477 GLsizei imageSize, const GLvoid *data)
4478 {
4479 GLint bytesPerRow, dstRowStride, srcRowStride;
4480 GLint i, rows;
4481 GLubyte *dstMap;
4482 const GLubyte *src;
4483 const gl_format texFormat = texImage->TexFormat;
4484 GLuint bw, bh;
4485
4486 if (dims != 2) {
4487 _mesa_problem(ctx, "Unexpected 1D/3D compressed texsubimage call");
4488 return;
4489 }
4490
4491 _mesa_get_format_block_size(texFormat, &bw, &bh);
4492
4493 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4494 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
4495 &ctx->Unpack,
4496 "glCompressedTexSubImage2D");
4497 if (!data)
4498 return;
4499
4500 srcRowStride = _mesa_format_row_stride(texFormat, width);
4501 src = (const GLubyte *) data;
4502
4503 /* Map dest texture buffer */
4504 ctx->Driver.MapTextureImage(ctx, texImage, 0,
4505 xoffset, yoffset, width, height,
4506 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
4507 &dstMap, &dstRowStride);
4508
4509 if (dstMap) {
4510 bytesPerRow = srcRowStride; /* bytes per row of blocks */
4511 rows = (height + bh - 1) / bh; /* rows in blocks */
4512
4513 /* copy rows of blocks */
4514 for (i = 0; i < rows; i++) {
4515 memcpy(dstMap, src, bytesPerRow);
4516 dstMap += dstRowStride;
4517 src += srcRowStride;
4518 }
4519
4520 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
4521 }
4522 else {
4523 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D");
4524 }
4525
4526 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
4527 }
4528