dc10797629ab8b09d805210f466ff956db79ea60
[mesa.git] / src / mesa / main / texstore.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (c) 2008-2009 VMware, Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * 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 "format_utils.h"
59 #include "image.h"
60 #include "macros.h"
61 #include "mipmap.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 "texcompress_bptc.h"
72 #include "teximage.h"
73 #include "texstore.h"
74 #include "enums.h"
75 #include "glformats.h"
76 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
77 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
78
79
80 enum {
81 ZERO = 4,
82 ONE = 5
83 };
84
85
86 /**
87 * Texture image storage function.
88 */
89 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
90
91
92 /**
93 * Make a temporary (color) texture image with GLfloat components.
94 * Apply all needed pixel unpacking and pixel transfer operations.
95 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
96 * Suppose the user specifies GL_LUMINANCE as the internal texture format
97 * but the graphics hardware doesn't support luminance textures. So, we might
98 * use an RGB hardware format instead.
99 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
100 *
101 * \param ctx the rendering context
102 * \param dims image dimensions: 1, 2 or 3
103 * \param logicalBaseFormat basic texture derived from the user's
104 * internal texture format value
105 * \param textureBaseFormat the actual basic format of the texture
106 * \param srcWidth source image width
107 * \param srcHeight source image height
108 * \param srcDepth source image depth
109 * \param srcFormat source image format
110 * \param srcType source image type
111 * \param srcAddr source image address
112 * \param srcPacking source image pixel packing
113 * \return resulting image with format = textureBaseFormat and type = GLfloat.
114 */
115 GLfloat *
116 _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
117 GLenum logicalBaseFormat,
118 GLenum textureBaseFormat,
119 GLint srcWidth, GLint srcHeight, GLint srcDepth,
120 GLenum srcFormat, GLenum srcType,
121 const GLvoid *srcAddr,
122 const struct gl_pixelstore_attrib *srcPacking,
123 GLbitfield transferOps)
124 {
125 GLfloat *tempImage;
126 const GLint components = _mesa_components_in_format(logicalBaseFormat);
127 const GLint srcStride =
128 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
129 GLfloat *dst;
130 GLint img, row;
131
132 ASSERT(dims >= 1 && dims <= 3);
133
134 ASSERT(logicalBaseFormat == GL_RGBA ||
135 logicalBaseFormat == GL_RGB ||
136 logicalBaseFormat == GL_RG ||
137 logicalBaseFormat == GL_RED ||
138 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
139 logicalBaseFormat == GL_LUMINANCE ||
140 logicalBaseFormat == GL_ALPHA ||
141 logicalBaseFormat == GL_INTENSITY ||
142 logicalBaseFormat == GL_DEPTH_COMPONENT);
143
144 ASSERT(textureBaseFormat == GL_RGBA ||
145 textureBaseFormat == GL_RGB ||
146 textureBaseFormat == GL_RG ||
147 textureBaseFormat == GL_RED ||
148 textureBaseFormat == GL_LUMINANCE_ALPHA ||
149 textureBaseFormat == GL_LUMINANCE ||
150 textureBaseFormat == GL_ALPHA ||
151 textureBaseFormat == GL_INTENSITY ||
152 textureBaseFormat == GL_DEPTH_COMPONENT);
153
154 tempImage = malloc(srcWidth * srcHeight * srcDepth
155 * components * sizeof(GLfloat));
156 if (!tempImage)
157 return NULL;
158
159 dst = tempImage;
160 for (img = 0; img < srcDepth; img++) {
161 const GLubyte *src
162 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
163 srcWidth, srcHeight,
164 srcFormat, srcType,
165 img, 0, 0);
166 for (row = 0; row < srcHeight; row++) {
167 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
168 dst, srcFormat, srcType, src,
169 srcPacking, transferOps);
170 dst += srcWidth * components;
171 src += srcStride;
172 }
173 }
174
175 if (logicalBaseFormat != textureBaseFormat) {
176 /* more work */
177 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
178 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
179 GLfloat *newImage;
180 GLint i, n;
181 GLubyte map[6];
182
183 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
184 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
185 textureBaseFormat == GL_LUMINANCE_ALPHA);
186
187 /* The actual texture format should have at least as many components
188 * as the logical texture format.
189 */
190 ASSERT(texComponents >= logComponents);
191
192 newImage = malloc(srcWidth * srcHeight * srcDepth
193 * texComponents * sizeof(GLfloat));
194 if (!newImage) {
195 free(tempImage);
196 return NULL;
197 }
198
199 _mesa_compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
200
201 n = srcWidth * srcHeight * srcDepth;
202 for (i = 0; i < n; i++) {
203 GLint k;
204 for (k = 0; k < texComponents; k++) {
205 GLint j = map[k];
206 if (j == ZERO)
207 newImage[i * texComponents + k] = 0.0F;
208 else if (j == ONE)
209 newImage[i * texComponents + k] = 1.0F;
210 else
211 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
212 }
213 }
214
215 free(tempImage);
216 tempImage = newImage;
217 }
218
219 return tempImage;
220 }
221
222
223 /**
224 * Make temporary image with uint pixel values. Used for unsigned
225 * integer-valued textures.
226 */
227 static GLuint *
228 make_temp_uint_image(struct gl_context *ctx, GLuint dims,
229 GLenum logicalBaseFormat,
230 GLenum textureBaseFormat,
231 GLint srcWidth, GLint srcHeight, GLint srcDepth,
232 GLenum srcFormat, GLenum srcType,
233 const GLvoid *srcAddr,
234 const struct gl_pixelstore_attrib *srcPacking)
235 {
236 GLuint *tempImage;
237 const GLint components = _mesa_components_in_format(logicalBaseFormat);
238 const GLint srcStride =
239 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
240 GLuint *dst;
241 GLint img, row;
242
243 ASSERT(dims >= 1 && dims <= 3);
244
245 ASSERT(logicalBaseFormat == GL_RGBA ||
246 logicalBaseFormat == GL_RGB ||
247 logicalBaseFormat == GL_RG ||
248 logicalBaseFormat == GL_RED ||
249 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
250 logicalBaseFormat == GL_LUMINANCE ||
251 logicalBaseFormat == GL_INTENSITY ||
252 logicalBaseFormat == GL_ALPHA);
253
254 ASSERT(textureBaseFormat == GL_RGBA ||
255 textureBaseFormat == GL_RGB ||
256 textureBaseFormat == GL_RG ||
257 textureBaseFormat == GL_RED ||
258 textureBaseFormat == GL_LUMINANCE_ALPHA ||
259 textureBaseFormat == GL_LUMINANCE ||
260 textureBaseFormat == GL_INTENSITY ||
261 textureBaseFormat == GL_ALPHA);
262
263 tempImage = malloc(srcWidth * srcHeight * srcDepth
264 * components * sizeof(GLuint));
265 if (!tempImage)
266 return NULL;
267
268 dst = tempImage;
269 for (img = 0; img < srcDepth; img++) {
270 const GLubyte *src
271 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
272 srcWidth, srcHeight,
273 srcFormat, srcType,
274 img, 0, 0);
275 for (row = 0; row < srcHeight; row++) {
276 _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
277 dst, srcFormat, srcType, src,
278 srcPacking);
279 dst += srcWidth * components;
280 src += srcStride;
281 }
282 }
283
284 if (logicalBaseFormat != textureBaseFormat) {
285 /* more work */
286 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
287 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
288 GLuint *newImage;
289 GLint i, n;
290 GLubyte map[6];
291
292 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
293 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
294 textureBaseFormat == GL_LUMINANCE_ALPHA);
295
296 /* The actual texture format should have at least as many components
297 * as the logical texture format.
298 */
299 ASSERT(texComponents >= logComponents);
300
301 newImage = malloc(srcWidth * srcHeight * srcDepth
302 * texComponents * sizeof(GLuint));
303 if (!newImage) {
304 free(tempImage);
305 return NULL;
306 }
307
308 _mesa_compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
309
310 n = srcWidth * srcHeight * srcDepth;
311 for (i = 0; i < n; i++) {
312 GLint k;
313 for (k = 0; k < texComponents; k++) {
314 GLint j = map[k];
315 if (j == ZERO)
316 newImage[i * texComponents + k] = 0;
317 else if (j == ONE)
318 newImage[i * texComponents + k] = 1;
319 else
320 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
321 }
322 }
323
324 free(tempImage);
325 tempImage = newImage;
326 }
327
328 return tempImage;
329 }
330
331
332
333 /**
334 * Make a temporary (color) texture image with GLubyte components.
335 * Apply all needed pixel unpacking and pixel transfer operations.
336 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
337 * Suppose the user specifies GL_LUMINANCE as the internal texture format
338 * but the graphics hardware doesn't support luminance textures. So, we might
339 * use an RGB hardware format instead.
340 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
341 *
342 * \param ctx the rendering context
343 * \param dims image dimensions: 1, 2 or 3
344 * \param logicalBaseFormat basic texture derived from the user's
345 * internal texture format value
346 * \param textureBaseFormat the actual basic format of the texture
347 * \param srcWidth source image width
348 * \param srcHeight source image height
349 * \param srcDepth source image depth
350 * \param srcFormat source image format
351 * \param srcType source image type
352 * \param srcAddr source image address
353 * \param srcPacking source image pixel packing
354 * \return resulting image with format = textureBaseFormat and type = GLubyte.
355 */
356 GLubyte *
357 _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
358 GLenum logicalBaseFormat,
359 GLenum textureBaseFormat,
360 GLint srcWidth, GLint srcHeight, GLint srcDepth,
361 GLenum srcFormat, GLenum srcType,
362 const GLvoid *srcAddr,
363 const struct gl_pixelstore_attrib *srcPacking)
364 {
365 GLuint transferOps = ctx->_ImageTransferState;
366 const GLint components = _mesa_components_in_format(logicalBaseFormat);
367 GLint img, row;
368 GLubyte *tempImage, *dst;
369
370 ASSERT(dims >= 1 && dims <= 3);
371
372 ASSERT(logicalBaseFormat == GL_RGBA ||
373 logicalBaseFormat == GL_RGB ||
374 logicalBaseFormat == GL_RG ||
375 logicalBaseFormat == GL_RED ||
376 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
377 logicalBaseFormat == GL_LUMINANCE ||
378 logicalBaseFormat == GL_ALPHA ||
379 logicalBaseFormat == GL_INTENSITY);
380
381 ASSERT(textureBaseFormat == GL_RGBA ||
382 textureBaseFormat == GL_RGB ||
383 textureBaseFormat == GL_RG ||
384 textureBaseFormat == GL_RED ||
385 textureBaseFormat == GL_LUMINANCE_ALPHA ||
386 textureBaseFormat == GL_LUMINANCE ||
387 textureBaseFormat == GL_ALPHA ||
388 textureBaseFormat == GL_INTENSITY);
389
390 /* unpack and transfer the source image */
391 tempImage = malloc(srcWidth * srcHeight * srcDepth
392 * components * sizeof(GLubyte));
393 if (!tempImage) {
394 return NULL;
395 }
396
397 dst = tempImage;
398 for (img = 0; img < srcDepth; img++) {
399 const GLint srcStride =
400 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
401 const GLubyte *src =
402 (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
403 srcWidth, srcHeight,
404 srcFormat, srcType,
405 img, 0, 0);
406 for (row = 0; row < srcHeight; row++) {
407 _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst,
408 srcFormat, srcType, src, srcPacking,
409 transferOps);
410 dst += srcWidth * components;
411 src += srcStride;
412 }
413 }
414
415 if (logicalBaseFormat != textureBaseFormat) {
416 /* one more conversion step */
417 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
418 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
419 GLubyte *newImage;
420 GLint i, n;
421 GLubyte map[6];
422
423 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
424 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
425 textureBaseFormat == GL_LUMINANCE_ALPHA);
426
427 /* The actual texture format should have at least as many components
428 * as the logical texture format.
429 */
430 ASSERT(texComponents >= logComponents);
431
432 newImage = malloc(srcWidth * srcHeight * srcDepth
433 * texComponents * sizeof(GLubyte));
434 if (!newImage) {
435 free(tempImage);
436 return NULL;
437 }
438
439 _mesa_compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
440
441 n = srcWidth * srcHeight * srcDepth;
442 for (i = 0; i < n; i++) {
443 GLint k;
444 for (k = 0; k < texComponents; k++) {
445 GLint j = map[k];
446 if (j == ZERO)
447 newImage[i * texComponents + k] = 0;
448 else if (j == ONE)
449 newImage[i * texComponents + k] = 255;
450 else
451 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
452 }
453 }
454
455 free(tempImage);
456 tempImage = newImage;
457 }
458
459 return tempImage;
460 }
461
462
463 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
464 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
465 static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE };
466
467
468 /**
469 * Teximage storage routine for when a simple memcpy will do.
470 * No pixel transfer operations or special texel encodings allowed.
471 * 1D, 2D and 3D images supported.
472 */
473 static void
474 memcpy_texture(struct gl_context *ctx,
475 GLuint dimensions,
476 mesa_format dstFormat,
477 GLint dstRowStride,
478 GLubyte **dstSlices,
479 GLint srcWidth, GLint srcHeight, GLint srcDepth,
480 GLenum srcFormat, GLenum srcType,
481 const GLvoid *srcAddr,
482 const struct gl_pixelstore_attrib *srcPacking)
483 {
484 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
485 srcFormat, srcType);
486 const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
487 srcWidth, srcHeight, srcFormat, srcType);
488 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
489 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
490 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
491 const GLint bytesPerRow = srcWidth * texelBytes;
492
493 if (dstRowStride == srcRowStride &&
494 dstRowStride == bytesPerRow) {
495 /* memcpy image by image */
496 GLint img;
497 for (img = 0; img < srcDepth; img++) {
498 GLubyte *dstImage = dstSlices[img];
499 memcpy(dstImage, srcImage, bytesPerRow * srcHeight);
500 srcImage += srcImageStride;
501 }
502 }
503 else {
504 /* memcpy row by row */
505 GLint img, row;
506 for (img = 0; img < srcDepth; img++) {
507 const GLubyte *srcRow = srcImage;
508 GLubyte *dstRow = dstSlices[img];
509 for (row = 0; row < srcHeight; row++) {
510 memcpy(dstRow, srcRow, bytesPerRow);
511 dstRow += dstRowStride;
512 srcRow += srcRowStride;
513 }
514 srcImage += srcImageStride;
515 }
516 }
517 }
518
519
520 /**
521 * General-case function for storing a color texture images with
522 * components that can be represented with ubytes. Example destination
523 * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.
524 */
525 static GLboolean
526 store_ubyte_texture(TEXSTORE_PARAMS)
527 {
528 const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
529 GLubyte *tempImage, *src;
530 GLint img;
531
532 tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
533 baseInternalFormat,
534 GL_RGBA,
535 srcWidth, srcHeight, srcDepth,
536 srcFormat, srcType, srcAddr,
537 srcPacking);
538 if (!tempImage)
539 return GL_FALSE;
540
541 /* This way we will use the RGB versions of the packing functions and it
542 * will work for both RGB and sRGB textures*/
543 dstFormat = _mesa_get_srgb_format_linear(dstFormat);
544
545 src = tempImage;
546 for (img = 0; img < srcDepth; img++) {
547 _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
548 src, srcRowStride,
549 dstSlices[img], dstRowStride);
550 src += srcHeight * srcRowStride;
551 }
552 free(tempImage);
553
554 return GL_TRUE;
555 }
556
557
558
559
560 /**
561 * Store a 32-bit integer or float depth component texture image.
562 */
563 static GLboolean
564 _mesa_texstore_z32(TEXSTORE_PARAMS)
565 {
566 const GLuint depthScale = 0xffffffff;
567 GLenum dstType;
568 (void) dims;
569 ASSERT(dstFormat == MESA_FORMAT_Z_UNORM32 ||
570 dstFormat == MESA_FORMAT_Z_FLOAT32);
571 ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
572
573 if (dstFormat == MESA_FORMAT_Z_UNORM32)
574 dstType = GL_UNSIGNED_INT;
575 else
576 dstType = GL_FLOAT;
577
578 {
579 /* general path */
580 GLint img, row;
581 for (img = 0; img < srcDepth; img++) {
582 GLubyte *dstRow = dstSlices[img];
583 for (row = 0; row < srcHeight; row++) {
584 const GLvoid *src = _mesa_image_address(dims, srcPacking,
585 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
586 _mesa_unpack_depth_span(ctx, srcWidth,
587 dstType, dstRow,
588 depthScale, srcType, src, srcPacking);
589 dstRow += dstRowStride;
590 }
591 }
592 }
593 return GL_TRUE;
594 }
595
596
597 /**
598 * Store a 24-bit integer depth component texture image.
599 */
600 static GLboolean
601 _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
602 {
603 const GLuint depthScale = 0xffffff;
604
605 (void) dims;
606 ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
607
608 {
609 /* general path */
610 GLint img, row;
611 for (img = 0; img < srcDepth; img++) {
612 GLubyte *dstRow = dstSlices[img];
613 for (row = 0; row < srcHeight; row++) {
614 const GLvoid *src = _mesa_image_address(dims, srcPacking,
615 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
616 _mesa_unpack_depth_span(ctx, srcWidth,
617 GL_UNSIGNED_INT, (GLuint *) dstRow,
618 depthScale, srcType, src, srcPacking);
619 dstRow += dstRowStride;
620 }
621 }
622 }
623 return GL_TRUE;
624 }
625
626
627 /**
628 * Store a 24-bit integer depth component texture image.
629 */
630 static GLboolean
631 _mesa_texstore_z24_x8(TEXSTORE_PARAMS)
632 {
633 const GLuint depthScale = 0xffffff;
634
635 (void) dims;
636 ASSERT(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
637
638 {
639 /* general path */
640 GLint img, row;
641 for (img = 0; img < srcDepth; img++) {
642 GLubyte *dstRow = dstSlices[img];
643 for (row = 0; row < srcHeight; row++) {
644 const GLvoid *src = _mesa_image_address(dims, srcPacking,
645 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
646 GLuint *dst = (GLuint *) dstRow;
647 GLint i;
648 _mesa_unpack_depth_span(ctx, srcWidth,
649 GL_UNSIGNED_INT, dst,
650 depthScale, srcType, src, srcPacking);
651 for (i = 0; i < srcWidth; i++)
652 dst[i] <<= 8;
653 dstRow += dstRowStride;
654 }
655 }
656 }
657 return GL_TRUE;
658 }
659
660
661 /**
662 * Store a 16-bit integer depth component texture image.
663 */
664 static GLboolean
665 _mesa_texstore_z16(TEXSTORE_PARAMS)
666 {
667 const GLuint depthScale = 0xffff;
668 (void) dims;
669 ASSERT(dstFormat == MESA_FORMAT_Z_UNORM16);
670 ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
671
672 {
673 /* general path */
674 GLint img, row;
675 for (img = 0; img < srcDepth; img++) {
676 GLubyte *dstRow = dstSlices[img];
677 for (row = 0; row < srcHeight; row++) {
678 const GLvoid *src = _mesa_image_address(dims, srcPacking,
679 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
680 GLushort *dst16 = (GLushort *) dstRow;
681 _mesa_unpack_depth_span(ctx, srcWidth,
682 GL_UNSIGNED_SHORT, dst16, depthScale,
683 srcType, src, srcPacking);
684 dstRow += dstRowStride;
685 }
686 }
687 }
688 return GL_TRUE;
689 }
690
691
692 /**
693 * Store an rgb565 or rgb565_rev texture image.
694 */
695 static GLboolean
696 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
697 {
698 ASSERT(dstFormat == MESA_FORMAT_B5G6R5_UNORM ||
699 dstFormat == MESA_FORMAT_R5G6B5_UNORM);
700 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
701
702 if (!ctx->_ImageTransferState &&
703 !srcPacking->SwapBytes &&
704 baseInternalFormat == GL_RGB &&
705 srcFormat == GL_RGB &&
706 srcType == GL_UNSIGNED_BYTE &&
707 dims == 2) {
708 /* do optimized tex store */
709 const GLint srcRowStride =
710 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
711 const GLubyte *src = (const GLubyte *)
712 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
713 srcFormat, srcType, 0, 0, 0);
714 GLubyte *dst = dstSlices[0];
715 GLint row, col;
716 for (row = 0; row < srcHeight; row++) {
717 const GLubyte *srcUB = (const GLubyte *) src;
718 GLushort *dstUS = (GLushort *) dst;
719 /* check for byteswapped format */
720 if (dstFormat == MESA_FORMAT_B5G6R5_UNORM) {
721 for (col = 0; col < srcWidth; col++) {
722 dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
723 srcUB += 3;
724 }
725 }
726 else {
727 for (col = 0; col < srcWidth; col++) {
728 dstUS[col] = PACK_COLOR_565( srcUB[2], srcUB[1], srcUB[0] );
729 srcUB += 3;
730 }
731 }
732 dst += dstRowStride;
733 src += srcRowStride;
734 }
735 return GL_TRUE;
736 } else {
737 return GL_FALSE;
738 }
739 }
740
741
742 /**
743 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
744 */
745 static GLboolean
746 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
747 {
748 const GLboolean littleEndian = _mesa_little_endian();
749
750 (void) ctx; (void) dims; (void) baseInternalFormat;
751
752 ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
753 (dstFormat == MESA_FORMAT_YCBCR_REV));
754 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
755 ASSERT(ctx->Extensions.MESA_ycbcr_texture);
756 ASSERT(srcFormat == GL_YCBCR_MESA);
757 ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
758 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
759 ASSERT(baseInternalFormat == GL_YCBCR_MESA);
760
761 /* always just memcpy since no pixel transfer ops apply */
762 memcpy_texture(ctx, dims,
763 dstFormat,
764 dstRowStride, dstSlices,
765 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
766 srcAddr, srcPacking);
767
768 /* Check if we need byte swapping */
769 /* XXX the logic here _might_ be wrong */
770 if (srcPacking->SwapBytes ^
771 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
772 (dstFormat == MESA_FORMAT_YCBCR_REV) ^
773 !littleEndian) {
774 GLint img, row;
775 for (img = 0; img < srcDepth; img++) {
776 GLubyte *dstRow = dstSlices[img];
777 for (row = 0; row < srcHeight; row++) {
778 _mesa_swap2((GLushort *) dstRow, srcWidth);
779 dstRow += dstRowStride;
780 }
781 }
782 }
783 return GL_TRUE;
784 }
785
786
787 /**
788 * Store a combined depth/stencil texture image.
789 */
790 static GLboolean
791 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
792 {
793 const GLuint depthScale = 0xffffff;
794 const GLint srcRowStride
795 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
796 GLint img, row;
797 GLuint *depth = malloc(srcWidth * sizeof(GLuint));
798 GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
799
800 ASSERT(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM);
801 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
802 srcFormat == GL_DEPTH_COMPONENT ||
803 srcFormat == GL_STENCIL_INDEX);
804 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
805 srcType == GL_UNSIGNED_INT_24_8_EXT ||
806 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
807
808 if (!depth || !stencil) {
809 free(depth);
810 free(stencil);
811 return GL_FALSE;
812 }
813
814 /* In case we only upload depth we need to preserve the stencil */
815 for (img = 0; img < srcDepth; img++) {
816 GLuint *dstRow = (GLuint *) dstSlices[img];
817 const GLubyte *src
818 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
819 srcWidth, srcHeight,
820 srcFormat, srcType,
821 img, 0, 0);
822 for (row = 0; row < srcHeight; row++) {
823 GLint i;
824 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
825
826 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
827 keepstencil = GL_TRUE;
828 }
829 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
830 keepdepth = GL_TRUE;
831 }
832
833 if (keepdepth == GL_FALSE)
834 /* the 24 depth bits will be in the low position: */
835 _mesa_unpack_depth_span(ctx, srcWidth,
836 GL_UNSIGNED_INT, /* dst type */
837 keepstencil ? depth : dstRow, /* dst addr */
838 depthScale,
839 srcType, src, srcPacking);
840
841 if (keepstencil == GL_FALSE)
842 /* get the 8-bit stencil values */
843 _mesa_unpack_stencil_span(ctx, srcWidth,
844 GL_UNSIGNED_BYTE, /* dst type */
845 stencil, /* dst addr */
846 srcType, src, srcPacking,
847 ctx->_ImageTransferState);
848
849 for (i = 0; i < srcWidth; i++) {
850 if (keepstencil)
851 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
852 else
853 dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
854 }
855 src += srcRowStride;
856 dstRow += dstRowStride / sizeof(GLuint);
857 }
858 }
859
860 free(depth);
861 free(stencil);
862 return GL_TRUE;
863 }
864
865
866 /**
867 * Store a combined depth/stencil texture image.
868 */
869 static GLboolean
870 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
871 {
872 const GLuint depthScale = 0xffffff;
873 const GLint srcRowStride
874 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
875 GLint img, row;
876 GLuint *depth;
877 GLubyte *stencil;
878
879 ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
880 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
881 srcFormat == GL_DEPTH_COMPONENT ||
882 srcFormat == GL_STENCIL_INDEX);
883 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
884 srcType == GL_UNSIGNED_INT_24_8_EXT ||
885 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
886
887 depth = malloc(srcWidth * sizeof(GLuint));
888 stencil = malloc(srcWidth * sizeof(GLubyte));
889
890 if (!depth || !stencil) {
891 free(depth);
892 free(stencil);
893 return GL_FALSE;
894 }
895
896 for (img = 0; img < srcDepth; img++) {
897 GLuint *dstRow = (GLuint *) dstSlices[img];
898 const GLubyte *src
899 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
900 srcWidth, srcHeight,
901 srcFormat, srcType,
902 img, 0, 0);
903 for (row = 0; row < srcHeight; row++) {
904 GLint i;
905 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
906
907 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
908 keepstencil = GL_TRUE;
909 }
910 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
911 keepdepth = GL_TRUE;
912 }
913
914 if (keepdepth == GL_FALSE)
915 /* the 24 depth bits will be in the low position: */
916 _mesa_unpack_depth_span(ctx, srcWidth,
917 GL_UNSIGNED_INT, /* dst type */
918 keepstencil ? depth : dstRow, /* dst addr */
919 depthScale,
920 srcType, src, srcPacking);
921
922 if (keepstencil == GL_FALSE)
923 /* get the 8-bit stencil values */
924 _mesa_unpack_stencil_span(ctx, srcWidth,
925 GL_UNSIGNED_BYTE, /* dst type */
926 stencil, /* dst addr */
927 srcType, src, srcPacking,
928 ctx->_ImageTransferState);
929
930 /* merge stencil values into depth values */
931 for (i = 0; i < srcWidth; i++) {
932 if (keepstencil)
933 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
934 else
935 dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
936
937 }
938 src += srcRowStride;
939 dstRow += dstRowStride / sizeof(GLuint);
940 }
941 }
942
943 free(depth);
944 free(stencil);
945
946 return GL_TRUE;
947 }
948
949
950 /**
951 * Store simple 8-bit/value stencil texture data.
952 */
953 static GLboolean
954 _mesa_texstore_s8(TEXSTORE_PARAMS)
955 {
956 ASSERT(dstFormat == MESA_FORMAT_S_UINT8);
957 ASSERT(srcFormat == GL_STENCIL_INDEX);
958
959 {
960 const GLint srcRowStride
961 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
962 GLint img, row;
963 GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
964
965 if (!stencil)
966 return GL_FALSE;
967
968 for (img = 0; img < srcDepth; img++) {
969 GLubyte *dstRow = dstSlices[img];
970 const GLubyte *src
971 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
972 srcWidth, srcHeight,
973 srcFormat, srcType,
974 img, 0, 0);
975 for (row = 0; row < srcHeight; row++) {
976 GLint i;
977
978 /* get the 8-bit stencil values */
979 _mesa_unpack_stencil_span(ctx, srcWidth,
980 GL_UNSIGNED_BYTE, /* dst type */
981 stencil, /* dst addr */
982 srcType, src, srcPacking,
983 ctx->_ImageTransferState);
984 /* merge stencil values into depth values */
985 for (i = 0; i < srcWidth; i++)
986 dstRow[i] = stencil[i];
987
988 src += srcRowStride;
989 dstRow += dstRowStride / sizeof(GLubyte);
990 }
991 }
992
993 free(stencil);
994 }
995
996 return GL_TRUE;
997 }
998
999
1000 static GLboolean
1001 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
1002 {
1003 GLint img, row;
1004 const GLint srcRowStride
1005 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
1006 / sizeof(uint64_t);
1007
1008 ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
1009 ASSERT(srcFormat == GL_DEPTH_STENCIL ||
1010 srcFormat == GL_DEPTH_COMPONENT ||
1011 srcFormat == GL_STENCIL_INDEX);
1012 ASSERT(srcFormat != GL_DEPTH_STENCIL ||
1013 srcType == GL_UNSIGNED_INT_24_8 ||
1014 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
1015
1016 /* In case we only upload depth we need to preserve the stencil */
1017 for (img = 0; img < srcDepth; img++) {
1018 uint64_t *dstRow = (uint64_t *) dstSlices[img];
1019 const uint64_t *src
1020 = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
1021 srcWidth, srcHeight,
1022 srcFormat, srcType,
1023 img, 0, 0);
1024 for (row = 0; row < srcHeight; row++) {
1025 /* The unpack functions with:
1026 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
1027 * only write their own dword, so the other dword (stencil
1028 * or depth) is preserved. */
1029 if (srcFormat != GL_STENCIL_INDEX)
1030 _mesa_unpack_depth_span(ctx, srcWidth,
1031 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
1032 dstRow, /* dst addr */
1033 ~0U, srcType, src, srcPacking);
1034
1035 if (srcFormat != GL_DEPTH_COMPONENT)
1036 _mesa_unpack_stencil_span(ctx, srcWidth,
1037 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
1038 dstRow, /* dst addr */
1039 srcType, src, srcPacking,
1040 ctx->_ImageTransferState);
1041
1042 src += srcRowStride;
1043 dstRow += dstRowStride / sizeof(uint64_t);
1044 }
1045 }
1046 return GL_TRUE;
1047 }
1048
1049 static GLboolean
1050 _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
1051 {
1052 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1053
1054 ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UINT);
1055 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1056
1057 {
1058 /* general path */
1059 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
1060 baseInternalFormat,
1061 baseFormat,
1062 srcWidth, srcHeight,
1063 srcDepth, srcFormat,
1064 srcType, srcAddr,
1065 srcPacking);
1066 const GLuint *src = tempImage;
1067 GLint img, row, col;
1068 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
1069 if (!tempImage)
1070 return GL_FALSE;
1071 for (img = 0; img < srcDepth; img++) {
1072 GLubyte *dstRow = dstSlices[img];
1073
1074 for (row = 0; row < srcHeight; row++) {
1075 GLuint *dstUI = (GLuint *) dstRow;
1076 if (is_unsigned) {
1077 for (col = 0; col < srcWidth; col++) {
1078 GLushort a,r,g,b;
1079 r = MIN2(src[RCOMP], 0x3ff);
1080 g = MIN2(src[GCOMP], 0x3ff);
1081 b = MIN2(src[BCOMP], 0x3ff);
1082 a = MIN2(src[ACOMP], 0x003);
1083 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
1084 src += 4;
1085 }
1086 } else {
1087 for (col = 0; col < srcWidth; col++) {
1088 GLushort a,r,g,b;
1089 r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
1090 g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
1091 b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
1092 a = CLAMP((GLint) src[ACOMP], 0, 0x003);
1093 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
1094 src += 4;
1095 }
1096 }
1097 dstRow += dstRowStride;
1098 }
1099 }
1100 free((void *) tempImage);
1101 }
1102 return GL_TRUE;
1103 }
1104
1105 static GLboolean
1106 _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
1107 {
1108 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1109
1110 ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UINT);
1111 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1112
1113 {
1114 /* general path */
1115 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
1116 baseInternalFormat,
1117 baseFormat,
1118 srcWidth, srcHeight,
1119 srcDepth, srcFormat,
1120 srcType, srcAddr,
1121 srcPacking);
1122 const GLuint *src = tempImage;
1123 GLint img, row, col;
1124 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
1125 if (!tempImage)
1126 return GL_FALSE;
1127 for (img = 0; img < srcDepth; img++) {
1128 GLubyte *dstRow = dstSlices[img];
1129
1130 for (row = 0; row < srcHeight; row++) {
1131 GLuint *dstUI = (GLuint *) dstRow;
1132 if (is_unsigned) {
1133 for (col = 0; col < srcWidth; col++) {
1134 GLushort a,r,g,b;
1135 r = MIN2(src[RCOMP], 0x3ff);
1136 g = MIN2(src[GCOMP], 0x3ff);
1137 b = MIN2(src[BCOMP], 0x3ff);
1138 a = MIN2(src[ACOMP], 0x003);
1139 dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
1140 src += 4;
1141 }
1142 } else {
1143 for (col = 0; col < srcWidth; col++) {
1144 GLushort a,r,g,b;
1145 r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
1146 g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
1147 b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
1148 a = CLAMP((GLint) src[ACOMP], 0, 0x003);
1149 dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
1150 src += 4;
1151 }
1152 }
1153 dstRow += dstRowStride;
1154 }
1155 }
1156 free((void *) tempImage);
1157 }
1158 return GL_TRUE;
1159 }
1160
1161
1162 static GLboolean
1163 texstore_depth_stencil(TEXSTORE_PARAMS)
1164 {
1165 static StoreTexImageFunc table[MESA_FORMAT_COUNT];
1166 static GLboolean initialized = GL_FALSE;
1167
1168 if (!initialized) {
1169 memset(table, 0, sizeof table);
1170
1171 table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8;
1172 table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24;
1173 table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16;
1174 table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_x8_z24;
1175 table[MESA_FORMAT_X8_UINT_Z24_UNORM] = _mesa_texstore_z24_x8;
1176 table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32;
1177 table[MESA_FORMAT_S_UINT8] = _mesa_texstore_s8;
1178 table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32;
1179 table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8;
1180
1181 initialized = GL_TRUE;
1182 }
1183
1184 ASSERT(table[dstFormat]);
1185 return table[dstFormat](ctx, dims, baseInternalFormat,
1186 dstFormat, dstRowStride, dstSlices,
1187 srcWidth, srcHeight, srcDepth,
1188 srcFormat, srcType, srcAddr, srcPacking);
1189 }
1190
1191 static GLboolean
1192 texstore_compressed(TEXSTORE_PARAMS)
1193 {
1194 static StoreTexImageFunc table[MESA_FORMAT_COUNT];
1195 static GLboolean initialized = GL_FALSE;
1196
1197 if (!initialized) {
1198 memset(table, 0, sizeof table);
1199
1200 table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
1201 table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
1202 table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
1203 table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
1204 table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
1205 table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
1206 table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
1207 table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
1208 table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
1209 table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
1210 table[MESA_FORMAT_R_RGTC1_UNORM] = _mesa_texstore_red_rgtc1;
1211 table[MESA_FORMAT_R_RGTC1_SNORM] = _mesa_texstore_signed_red_rgtc1;
1212 table[MESA_FORMAT_RG_RGTC2_UNORM] = _mesa_texstore_rg_rgtc2;
1213 table[MESA_FORMAT_RG_RGTC2_SNORM] = _mesa_texstore_signed_rg_rgtc2;
1214 table[MESA_FORMAT_L_LATC1_UNORM] = _mesa_texstore_red_rgtc1;
1215 table[MESA_FORMAT_L_LATC1_SNORM] = _mesa_texstore_signed_red_rgtc1;
1216 table[MESA_FORMAT_LA_LATC2_UNORM] = _mesa_texstore_rg_rgtc2;
1217 table[MESA_FORMAT_LA_LATC2_SNORM] = _mesa_texstore_signed_rg_rgtc2;
1218 table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
1219 table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8;
1220 table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8;
1221 table[MESA_FORMAT_ETC2_RGBA8_EAC] = _mesa_texstore_etc2_rgba8_eac;
1222 table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = _mesa_texstore_etc2_srgb8_alpha8_eac;
1223 table[MESA_FORMAT_ETC2_R11_EAC] = _mesa_texstore_etc2_r11_eac;
1224 table[MESA_FORMAT_ETC2_RG11_EAC] = _mesa_texstore_etc2_rg11_eac;
1225 table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = _mesa_texstore_etc2_signed_r11_eac;
1226 table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = _mesa_texstore_etc2_signed_rg11_eac;
1227 table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] =
1228 _mesa_texstore_etc2_rgb8_punchthrough_alpha1;
1229 table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] =
1230 _mesa_texstore_etc2_srgb8_punchthrough_alpha1;
1231
1232 table[MESA_FORMAT_BPTC_RGBA_UNORM] =
1233 _mesa_texstore_bptc_rgba_unorm;
1234 table[MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM] =
1235 _mesa_texstore_bptc_rgba_unorm;
1236 table[MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT] =
1237 _mesa_texstore_bptc_rgb_signed_float;
1238 table[MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT] =
1239 _mesa_texstore_bptc_rgb_unsigned_float;
1240
1241 initialized = GL_TRUE;
1242 }
1243
1244 ASSERT(table[dstFormat]);
1245 return table[dstFormat](ctx, dims, baseInternalFormat,
1246 dstFormat, dstRowStride, dstSlices,
1247 srcWidth, srcHeight, srcDepth,
1248 srcFormat, srcType, srcAddr, srcPacking);
1249 }
1250
1251 static void
1252 invert_swizzle(uint8_t dst[4], const uint8_t src[4])
1253 {
1254 int i, j;
1255
1256 dst[0] = MESA_FORMAT_SWIZZLE_NONE;
1257 dst[1] = MESA_FORMAT_SWIZZLE_NONE;
1258 dst[2] = MESA_FORMAT_SWIZZLE_NONE;
1259 dst[3] = MESA_FORMAT_SWIZZLE_NONE;
1260
1261 for (i = 0; i < 4; ++i)
1262 for (j = 0; j < 4; ++j)
1263 if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE)
1264 dst[i] = j;
1265 }
1266
1267 /** Store a texture by per-channel conversions and swizzling.
1268 *
1269 * This function attempts to perform a texstore operation by doing simple
1270 * per-channel conversions and swizzling. This covers a huge chunk of the
1271 * texture storage operations that anyone cares about. If this function is
1272 * incapable of performing the operation, it bails and returns GL_FALSE.
1273 */
1274 static GLboolean
1275 texstore_swizzle(TEXSTORE_PARAMS)
1276 {
1277 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
1278 srcFormat, srcType);
1279 const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
1280 srcWidth, srcHeight, srcFormat, srcType);
1281 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dims,
1282 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
1283 const int src_components = _mesa_components_in_format(srcFormat);
1284
1285 GLubyte swizzle[4], rgba2base[6], base2src[6], rgba2dst[4], dst2rgba[4];
1286 const GLubyte *swap;
1287 GLenum dst_type;
1288 int dst_components;
1289 bool is_array, normalized, need_swap;
1290 GLint i, img, row;
1291 const GLubyte *src_row;
1292 GLubyte *dst_row;
1293
1294 is_array = _mesa_format_to_array(dstFormat, &dst_type, &dst_components,
1295 rgba2dst, &normalized);
1296
1297 if (!is_array)
1298 return GL_FALSE;
1299
1300 if (srcFormat == GL_COLOR_INDEX)
1301 return GL_FALSE;
1302
1303 if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat))
1304 return GL_FALSE;
1305
1306 switch (srcType) {
1307 case GL_FLOAT:
1308 case GL_UNSIGNED_BYTE:
1309 case GL_BYTE:
1310 case GL_UNSIGNED_SHORT:
1311 case GL_SHORT:
1312 case GL_UNSIGNED_INT:
1313 case GL_INT:
1314 /* If wa have to swap bytes in a multi-byte datatype, that means
1315 * we're not doing an array conversion anymore */
1316 if (srcPacking->SwapBytes)
1317 return GL_FALSE;
1318 need_swap = false;
1319 break;
1320 case GL_UNSIGNED_INT_8_8_8_8:
1321 need_swap = srcPacking->SwapBytes;
1322 if (_mesa_little_endian())
1323 need_swap = !need_swap;
1324 srcType = GL_UNSIGNED_BYTE;
1325 break;
1326 case GL_UNSIGNED_INT_8_8_8_8_REV:
1327 need_swap = srcPacking->SwapBytes;
1328 if (!_mesa_little_endian())
1329 need_swap = !need_swap;
1330 srcType = GL_UNSIGNED_BYTE;
1331 break;
1332 default:
1333 return GL_FALSE;
1334 }
1335 swap = need_swap ? map_3210 : map_identity;
1336
1337 _mesa_compute_component_mapping(srcFormat, baseInternalFormat, base2src);
1338 _mesa_compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);
1339 invert_swizzle(dst2rgba, rgba2dst);
1340
1341 for (i = 0; i < 4; i++) {
1342 if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE)
1343 swizzle[i] = MESA_FORMAT_SWIZZLE_NONE;
1344 else
1345 swizzle[i] = swap[base2src[rgba2base[dst2rgba[i]]]];
1346 }
1347
1348 /* Is it normalized? */
1349 normalized |= !_mesa_is_enum_format_integer(srcFormat);
1350
1351 for (img = 0; img < srcDepth; img++) {
1352 if (dstRowStride == srcWidth * dst_components &&
1353 srcRowStride == srcWidth * src_components) {
1354 _mesa_swizzle_and_convert(dstSlices[img], dst_type, dst_components,
1355 srcImage, srcType, src_components,
1356 swizzle, normalized, srcWidth * srcHeight);
1357 } else {
1358 src_row = srcImage;
1359 dst_row = dstSlices[img];
1360 for (row = 0; row < srcHeight; row++) {
1361 _mesa_swizzle_and_convert(dst_row, dst_type, dst_components,
1362 src_row, srcType, src_components,
1363 swizzle, normalized, srcWidth);
1364 dst_row += dstRowStride;
1365 src_row += srcRowStride;
1366 }
1367 }
1368 srcImage += srcImageStride;
1369 }
1370
1371 return GL_TRUE;
1372 }
1373
1374
1375 /** Stores a texture by converting float and then to the texture format
1376 *
1377 * This function performs a texstore operation by converting to float,
1378 * applying pixel transfer ops, and then converting to the texture's
1379 * internal format using pixel store functions. This function will work
1380 * for any rgb or srgb textore format.
1381 */
1382 static GLboolean
1383 texstore_via_float(TEXSTORE_PARAMS)
1384 {
1385 GLuint i, img, row;
1386 const GLint src_stride =
1387 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1388 float *tmp_row;
1389 bool need_convert;
1390 uint8_t *src_row, *dst_row, map[4], rgba2base[6], base2rgba[6];
1391
1392 tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row));
1393 if (!tmp_row)
1394 return GL_FALSE;
1395
1396 /* The GL spec (4.0, compatibility profile) only specifies srgb
1397 * conversion as something that is done in the sampler during the
1398 * filtering process before the colors are handed to the shader.
1399 * Furthermore, the flowchart (Figure 3.7 in the 4.0 compatibility spec)
1400 * does not list RGB <-> sRGB conversions anywhere. Therefore, we just
1401 * treat sRGB formats the same as RGB formats for the purposes of
1402 * texture upload and transfer ops.
1403 */
1404 dstFormat = _mesa_get_srgb_format_linear(dstFormat);
1405
1406 need_convert = false;
1407 if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) {
1408 _mesa_compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba);
1409 _mesa_compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);
1410 for (i = 0; i < 4; ++i) {
1411 map[i] = base2rgba[rgba2base[i]];
1412 if (map[i] != i)
1413 need_convert = true;
1414 }
1415 }
1416
1417 for (img = 0; img < srcDepth; img++) {
1418 dst_row = dstSlices[img];
1419 src_row = _mesa_image_address(dims, srcPacking, srcAddr,
1420 srcWidth, srcHeight,
1421 srcFormat, srcType,
1422 img, 0, 0);
1423 for (row = 0; row < srcHeight; row++) {
1424 _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, tmp_row,
1425 srcFormat, srcType, src_row,
1426 srcPacking, ctx->_ImageTransferState);
1427 if (need_convert)
1428 _mesa_swizzle_and_convert(tmp_row, GL_FLOAT, 4,
1429 tmp_row, GL_FLOAT, 4,
1430 map, false, srcWidth);
1431 _mesa_pack_float_rgba_row(dstFormat, srcWidth,
1432 (const GLfloat (*)[4])tmp_row,
1433 dst_row);
1434 dst_row += dstRowStride;
1435 src_row += src_stride;
1436 }
1437 }
1438
1439 free(tmp_row);
1440
1441 return GL_TRUE;
1442 }
1443
1444 /** Stores an integer rgba texture
1445 *
1446 * This function performs an integer texture storage operation by unpacking
1447 * the texture to 32-bit integers, and repacking it into the internal
1448 * format of the texture. This will work for any integer rgb texture
1449 * storage operation.
1450 */
1451 static GLboolean
1452 texstore_rgba_integer(TEXSTORE_PARAMS)
1453 {
1454 GLuint i, img, row, *tmp_row;
1455 GLenum dst_type, tmp_type;
1456 const GLint src_stride =
1457 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1458 int num_dst_components;
1459 bool is_array, normalized;
1460 uint8_t *src_row, *dst_row;
1461 uint8_t swizzle[4], rgba2base[6], base2rgba[6], rgba2dst[4], dst2rgba[4];
1462
1463 tmp_row = malloc(srcWidth * 4 * sizeof(*tmp_row));
1464 if (!tmp_row)
1465 return GL_FALSE;
1466
1467 is_array = _mesa_format_to_array(dstFormat, &dst_type, &num_dst_components,
1468 rgba2dst, &normalized);
1469
1470 assert(is_array && !normalized);
1471
1472 if (!is_array) {
1473 free(tmp_row);
1474 return GL_FALSE;
1475 }
1476
1477 invert_swizzle(dst2rgba, rgba2dst);
1478 _mesa_compute_component_mapping(GL_RGBA, baseInternalFormat, base2rgba);
1479 _mesa_compute_component_mapping(baseInternalFormat, GL_RGBA, rgba2base);
1480
1481 for (i = 0; i < 4; ++i) {
1482 if (dst2rgba[i] == MESA_FORMAT_SWIZZLE_NONE)
1483 swizzle[i] = MESA_FORMAT_SWIZZLE_NONE;
1484 else
1485 swizzle[i] = base2rgba[rgba2base[dst2rgba[i]]];
1486 }
1487
1488 if (_mesa_is_type_unsigned(srcType)) {
1489 tmp_type = GL_UNSIGNED_INT;
1490 } else {
1491 tmp_type = GL_INT;
1492 }
1493
1494 for (img = 0; img < srcDepth; img++) {
1495 dst_row = dstSlices[img];
1496 src_row = _mesa_image_address(dims, srcPacking, srcAddr,
1497 srcWidth, srcHeight,
1498 srcFormat, srcType,
1499 img, 0, 0);
1500 for (row = 0; row < srcHeight; row++) {
1501 _mesa_unpack_color_span_uint(ctx, srcWidth, GL_RGBA, tmp_row,
1502 srcFormat, srcType, src_row, srcPacking);
1503 _mesa_swizzle_and_convert(dst_row, dst_type, num_dst_components,
1504 tmp_row, tmp_type, 4,
1505 swizzle, false, srcWidth);
1506 dst_row += dstRowStride;
1507 src_row += src_stride;
1508 }
1509 }
1510
1511 free(tmp_row);
1512
1513 return GL_TRUE;
1514 }
1515
1516 static GLboolean
1517 texstore_rgba(TEXSTORE_PARAMS)
1518 {
1519 static StoreTexImageFunc table[MESA_FORMAT_COUNT];
1520 static GLboolean initialized = GL_FALSE;
1521
1522 if (!initialized) {
1523 memset(table, 0, sizeof table);
1524
1525 table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565;
1526 table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565;
1527 table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
1528 table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
1529
1530 table[MESA_FORMAT_B10G10R10A2_UINT] = _mesa_texstore_argb2101010_uint;
1531 table[MESA_FORMAT_R10G10B10A2_UINT] = _mesa_texstore_abgr2101010_uint;
1532
1533 initialized = GL_TRUE;
1534 }
1535
1536 if (table[dstFormat] && table[dstFormat](ctx, dims, baseInternalFormat,
1537 dstFormat, dstRowStride, dstSlices,
1538 srcWidth, srcHeight, srcDepth,
1539 srcFormat, srcType, srcAddr,
1540 srcPacking)) {
1541 return GL_TRUE;
1542 }
1543
1544 if (texstore_swizzle(ctx, dims, baseInternalFormat,
1545 dstFormat,
1546 dstRowStride, dstSlices,
1547 srcWidth, srcHeight, srcDepth,
1548 srcFormat, srcType, srcAddr, srcPacking)) {
1549 return GL_TRUE;
1550 }
1551
1552 if (_mesa_is_format_integer(dstFormat)) {
1553 return texstore_rgba_integer(ctx, dims, baseInternalFormat,
1554 dstFormat, dstRowStride, dstSlices,
1555 srcWidth, srcHeight, srcDepth,
1556 srcFormat, srcType, srcAddr,
1557 srcPacking);
1558 } else if (_mesa_get_format_max_bits(dstFormat) <= 8 &&
1559 !_mesa_is_format_signed(dstFormat)) {
1560 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1561 dstFormat,
1562 dstRowStride, dstSlices,
1563 srcWidth, srcHeight, srcDepth,
1564 srcFormat, srcType, srcAddr, srcPacking);
1565 } else {
1566 return texstore_via_float(ctx, dims, baseInternalFormat,
1567 dstFormat, dstRowStride, dstSlices,
1568 srcWidth, srcHeight, srcDepth,
1569 srcFormat, srcType, srcAddr,
1570 srcPacking);
1571 }
1572 }
1573
1574 GLboolean
1575 _mesa_texstore_needs_transfer_ops(struct gl_context *ctx,
1576 GLenum baseInternalFormat,
1577 mesa_format dstFormat)
1578 {
1579 GLenum dstType;
1580
1581 /* There are different rules depending on the base format. */
1582 switch (baseInternalFormat) {
1583 case GL_DEPTH_COMPONENT:
1584 case GL_DEPTH_STENCIL:
1585 return ctx->Pixel.DepthScale != 1.0f ||
1586 ctx->Pixel.DepthBias != 0.0f;
1587
1588 case GL_STENCIL_INDEX:
1589 return GL_FALSE;
1590
1591 default:
1592 /* Color formats.
1593 * Pixel transfer ops (scale, bias, table lookup) do not apply
1594 * to integer formats.
1595 */
1596 dstType = _mesa_get_format_datatype(dstFormat);
1597
1598 return dstType != GL_INT && dstType != GL_UNSIGNED_INT &&
1599 ctx->_ImageTransferState;
1600 }
1601 }
1602
1603
1604 GLboolean
1605 _mesa_texstore_can_use_memcpy(struct gl_context *ctx,
1606 GLenum baseInternalFormat, mesa_format dstFormat,
1607 GLenum srcFormat, GLenum srcType,
1608 const struct gl_pixelstore_attrib *srcPacking)
1609 {
1610 if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
1611 return GL_FALSE;
1612 }
1613
1614 /* The base internal format and the base Mesa format must match. */
1615 if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) {
1616 return GL_FALSE;
1617 }
1618
1619 /* The Mesa format must match the input format and type. */
1620 if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1621 srcPacking->SwapBytes)) {
1622 return GL_FALSE;
1623 }
1624
1625 /* Depth texture data needs clamping in following cases:
1626 * - Floating point dstFormat with signed srcType: clamp to [0.0, 1.0].
1627 * - Fixed point dstFormat with signed srcType: clamp to [0, 2^n -1].
1628 *
1629 * All the cases except one (float dstFormat with float srcType) are ruled
1630 * out by _mesa_format_matches_format_and_type() check above. Handle the
1631 * remaining case here.
1632 */
1633 if ((baseInternalFormat == GL_DEPTH_COMPONENT ||
1634 baseInternalFormat == GL_DEPTH_STENCIL) &&
1635 (srcType == GL_FLOAT ||
1636 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)) {
1637 return GL_FALSE;
1638 }
1639
1640 return GL_TRUE;
1641 }
1642
1643 static GLboolean
1644 _mesa_texstore_memcpy(TEXSTORE_PARAMS)
1645 {
1646 if (!_mesa_texstore_can_use_memcpy(ctx, baseInternalFormat, dstFormat,
1647 srcFormat, srcType, srcPacking)) {
1648 return GL_FALSE;
1649 }
1650
1651 memcpy_texture(ctx, dims,
1652 dstFormat,
1653 dstRowStride, dstSlices,
1654 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1655 srcAddr, srcPacking);
1656 return GL_TRUE;
1657 }
1658 /**
1659 * Store user data into texture memory.
1660 * Called via glTex[Sub]Image1/2/3D()
1661 * \return GL_TRUE for success, GL_FALSE for failure (out of memory).
1662 */
1663 GLboolean
1664 _mesa_texstore(TEXSTORE_PARAMS)
1665 {
1666 if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat,
1667 dstFormat,
1668 dstRowStride, dstSlices,
1669 srcWidth, srcHeight, srcDepth,
1670 srcFormat, srcType, srcAddr, srcPacking)) {
1671 return GL_TRUE;
1672 }
1673
1674 if (_mesa_is_depth_or_stencil_format(baseInternalFormat)) {
1675 return texstore_depth_stencil(ctx, dims, baseInternalFormat,
1676 dstFormat, dstRowStride, dstSlices,
1677 srcWidth, srcHeight, srcDepth,
1678 srcFormat, srcType, srcAddr, srcPacking);
1679 } else if (_mesa_is_format_compressed(dstFormat)) {
1680 return texstore_compressed(ctx, dims, baseInternalFormat,
1681 dstFormat, dstRowStride, dstSlices,
1682 srcWidth, srcHeight, srcDepth,
1683 srcFormat, srcType, srcAddr, srcPacking);
1684 } else {
1685 return texstore_rgba(ctx, dims, baseInternalFormat,
1686 dstFormat, dstRowStride, dstSlices,
1687 srcWidth, srcHeight, srcDepth,
1688 srcFormat, srcType, srcAddr, srcPacking);
1689 }
1690 }
1691
1692
1693 /**
1694 * Normally, we'll only _write_ texel data to a texture when we map it.
1695 * But if the user is providing depth or stencil values and the texture
1696 * image is a combined depth/stencil format, we'll actually read from
1697 * the texture buffer too (in order to insert the depth or stencil values.
1698 * \param userFormat the user-provided image format
1699 * \param texFormat the destination texture format
1700 */
1701 static GLbitfield
1702 get_read_write_mode(GLenum userFormat, mesa_format texFormat)
1703 {
1704 if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
1705 && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
1706 return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
1707 else
1708 return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
1709 }
1710
1711
1712 /**
1713 * Helper function for storing 1D, 2D, 3D whole and subimages into texture
1714 * memory.
1715 * The source of the image data may be user memory or a PBO. In the later
1716 * case, we'll map the PBO, copy from it, then unmap it.
1717 */
1718 static void
1719 store_texsubimage(struct gl_context *ctx,
1720 struct gl_texture_image *texImage,
1721 GLint xoffset, GLint yoffset, GLint zoffset,
1722 GLint width, GLint height, GLint depth,
1723 GLenum format, GLenum type, const GLvoid *pixels,
1724 const struct gl_pixelstore_attrib *packing,
1725 const char *caller)
1726
1727 {
1728 const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat);
1729 const GLenum target = texImage->TexObject->Target;
1730 GLboolean success = GL_FALSE;
1731 GLuint dims, slice, numSlices = 1, sliceOffset = 0;
1732 GLint srcImageStride = 0;
1733 const GLubyte *src;
1734
1735 assert(xoffset + width <= texImage->Width);
1736 assert(yoffset + height <= texImage->Height);
1737 assert(zoffset + depth <= texImage->Depth);
1738
1739 switch (target) {
1740 case GL_TEXTURE_1D:
1741 dims = 1;
1742 break;
1743 case GL_TEXTURE_2D_ARRAY:
1744 case GL_TEXTURE_CUBE_MAP_ARRAY:
1745 case GL_TEXTURE_3D:
1746 dims = 3;
1747 break;
1748 default:
1749 dims = 2;
1750 }
1751
1752 /* get pointer to src pixels (may be in a pbo which we'll map here) */
1753 src = (const GLubyte *)
1754 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
1755 format, type, pixels, packing, caller);
1756 if (!src)
1757 return;
1758
1759 /* compute slice info (and do some sanity checks) */
1760 switch (target) {
1761 case GL_TEXTURE_2D:
1762 case GL_TEXTURE_RECTANGLE:
1763 case GL_TEXTURE_CUBE_MAP:
1764 case GL_TEXTURE_EXTERNAL_OES:
1765 /* one image slice, nothing special needs to be done */
1766 break;
1767 case GL_TEXTURE_1D:
1768 assert(height == 1);
1769 assert(depth == 1);
1770 assert(yoffset == 0);
1771 assert(zoffset == 0);
1772 break;
1773 case GL_TEXTURE_1D_ARRAY:
1774 assert(depth == 1);
1775 assert(zoffset == 0);
1776 numSlices = height;
1777 sliceOffset = yoffset;
1778 height = 1;
1779 yoffset = 0;
1780 srcImageStride = _mesa_image_row_stride(packing, width, format, type);
1781 break;
1782 case GL_TEXTURE_2D_ARRAY:
1783 numSlices = depth;
1784 sliceOffset = zoffset;
1785 depth = 1;
1786 zoffset = 0;
1787 srcImageStride = _mesa_image_image_stride(packing, width, height,
1788 format, type);
1789 break;
1790 case GL_TEXTURE_3D:
1791 /* we'll store 3D images as a series of slices */
1792 numSlices = depth;
1793 sliceOffset = zoffset;
1794 srcImageStride = _mesa_image_image_stride(packing, width, height,
1795 format, type);
1796 break;
1797 case GL_TEXTURE_CUBE_MAP_ARRAY:
1798 numSlices = depth;
1799 sliceOffset = zoffset;
1800 srcImageStride = _mesa_image_image_stride(packing, width, height,
1801 format, type);
1802 break;
1803 default:
1804 _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
1805 return;
1806 }
1807
1808 assert(numSlices == 1 || srcImageStride != 0);
1809
1810 for (slice = 0; slice < numSlices; slice++) {
1811 GLubyte *dstMap;
1812 GLint dstRowStride;
1813
1814 ctx->Driver.MapTextureImage(ctx, texImage,
1815 slice + sliceOffset,
1816 xoffset, yoffset, width, height,
1817 mapMode, &dstMap, &dstRowStride);
1818 if (dstMap) {
1819 /* Note: we're only storing a 2D (or 1D) slice at a time but we need
1820 * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
1821 * used for 3D images.
1822 */
1823 success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
1824 texImage->TexFormat,
1825 dstRowStride,
1826 &dstMap,
1827 width, height, 1, /* w, h, d */
1828 format, type, src, packing);
1829
1830 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
1831 }
1832
1833 src += srcImageStride;
1834
1835 if (!success)
1836 break;
1837 }
1838
1839 if (!success)
1840 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
1841
1842 _mesa_unmap_teximage_pbo(ctx, packing);
1843 }
1844
1845
1846
1847 /**
1848 * Fallback code for ctx->Driver.TexImage().
1849 * Basically, allocate storage for the texture image, then copy the
1850 * user's image into it.
1851 */
1852 void
1853 _mesa_store_teximage(struct gl_context *ctx,
1854 GLuint dims,
1855 struct gl_texture_image *texImage,
1856 GLenum format, GLenum type, const GLvoid *pixels,
1857 const struct gl_pixelstore_attrib *packing)
1858 {
1859 assert(dims == 1 || dims == 2 || dims == 3);
1860
1861 if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
1862 return;
1863
1864 /* allocate storage for texture data */
1865 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
1866 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
1867 return;
1868 }
1869
1870 store_texsubimage(ctx, texImage,
1871 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth,
1872 format, type, pixels, packing, "glTexImage");
1873 }
1874
1875
1876 /*
1877 * Fallback for Driver.TexSubImage().
1878 */
1879 void
1880 _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims,
1881 struct gl_texture_image *texImage,
1882 GLint xoffset, GLint yoffset, GLint zoffset,
1883 GLint width, GLint height, GLint depth,
1884 GLenum format, GLenum type, const void *pixels,
1885 const struct gl_pixelstore_attrib *packing)
1886 {
1887 store_texsubimage(ctx, texImage,
1888 xoffset, yoffset, zoffset, width, height, depth,
1889 format, type, pixels, packing, "glTexSubImage");
1890 }
1891
1892 static void
1893 clear_image_to_zero(GLubyte *dstMap, GLint dstRowStride,
1894 GLsizei width, GLsizei height,
1895 GLsizei clearValueSize)
1896 {
1897 GLsizei y;
1898
1899 for (y = 0; y < height; y++) {
1900 memset(dstMap, 0, clearValueSize * width);
1901 dstMap += dstRowStride;
1902 }
1903 }
1904
1905 static void
1906 clear_image_to_value(GLubyte *dstMap, GLint dstRowStride,
1907 GLsizei width, GLsizei height,
1908 const GLvoid *clearValue,
1909 GLsizei clearValueSize)
1910 {
1911 GLsizei y, x;
1912
1913 for (y = 0; y < height; y++) {
1914 for (x = 0; x < width; x++) {
1915 memcpy(dstMap, clearValue, clearValueSize);
1916 dstMap += clearValueSize;
1917 }
1918 dstMap += dstRowStride - clearValueSize * width;
1919 }
1920 }
1921
1922 /*
1923 * Fallback for Driver.ClearTexSubImage().
1924 */
1925 void
1926 _mesa_store_cleartexsubimage(struct gl_context *ctx,
1927 struct gl_texture_image *texImage,
1928 GLint xoffset, GLint yoffset, GLint zoffset,
1929 GLsizei width, GLsizei height, GLsizei depth,
1930 const GLvoid *clearValue)
1931 {
1932 GLubyte *dstMap;
1933 GLint dstRowStride;
1934 GLsizeiptr clearValueSize;
1935 GLsizei z;
1936
1937 clearValueSize = _mesa_get_format_bytes(texImage->TexFormat);
1938
1939 for (z = 0; z < depth; z++) {
1940 ctx->Driver.MapTextureImage(ctx, texImage,
1941 z + zoffset, xoffset, yoffset,
1942 width, height,
1943 GL_MAP_WRITE_BIT,
1944 &dstMap, &dstRowStride);
1945 if (dstMap == NULL) {
1946 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearTex*Image");
1947 return;
1948 }
1949
1950 if (clearValue) {
1951 clear_image_to_value(dstMap, dstRowStride,
1952 width, height,
1953 clearValue,
1954 clearValueSize);
1955 } else {
1956 clear_image_to_zero(dstMap, dstRowStride,
1957 width, height,
1958 clearValueSize);
1959 }
1960
1961 ctx->Driver.UnmapTextureImage(ctx, texImage, z + zoffset);
1962 }
1963 }
1964
1965 /**
1966 * Fallback for Driver.CompressedTexImage()
1967 */
1968 void
1969 _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
1970 struct gl_texture_image *texImage,
1971 GLsizei imageSize, const GLvoid *data)
1972 {
1973 /* only 2D and 3D compressed images are supported at this time */
1974 if (dims == 1) {
1975 _mesa_problem(ctx, "Unexpected glCompressedTexImage1D call");
1976 return;
1977 }
1978
1979 /* This is pretty simple, because unlike the general texstore path we don't
1980 * have to worry about the usual image unpacking or image transfer
1981 * operations.
1982 */
1983 ASSERT(texImage);
1984 ASSERT(texImage->Width > 0);
1985 ASSERT(texImage->Height > 0);
1986 ASSERT(texImage->Depth > 0);
1987
1988 /* allocate storage for texture data */
1989 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
1990 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage%uD", dims);
1991 return;
1992 }
1993
1994 _mesa_store_compressed_texsubimage(ctx, dims, texImage,
1995 0, 0, 0,
1996 texImage->Width, texImage->Height, texImage->Depth,
1997 texImage->TexFormat,
1998 imageSize, data);
1999 }
2000
2001
2002 /**
2003 * Compute compressed_pixelstore parameters for copying compressed
2004 * texture data.
2005 * \param dims number of texture image dimensions: 1, 2 or 3
2006 * \param texFormat the compressed texture format
2007 * \param width, height, depth size of image to copy
2008 * \param packing pixelstore parameters describing user-space image packing
2009 * \param store returns the compressed_pixelstore parameters
2010 */
2011 void
2012 _mesa_compute_compressed_pixelstore(GLuint dims, mesa_format texFormat,
2013 GLsizei width, GLsizei height,
2014 GLsizei depth,
2015 const struct gl_pixelstore_attrib *packing,
2016 struct compressed_pixelstore *store)
2017 {
2018 GLuint bw, bh;
2019
2020 _mesa_get_format_block_size(texFormat, &bw, &bh);
2021
2022 store->SkipBytes = 0;
2023 store->TotalBytesPerRow = store->CopyBytesPerRow =
2024 _mesa_format_row_stride(texFormat, width);
2025 store->TotalRowsPerSlice = store->CopyRowsPerSlice =
2026 (height + bh - 1) / bh;
2027 store->CopySlices = depth;
2028
2029 if (packing->CompressedBlockWidth &&
2030 packing->CompressedBlockSize) {
2031
2032 bw = packing->CompressedBlockWidth;
2033
2034 if (packing->RowLength) {
2035 store->TotalBytesPerRow = packing->CompressedBlockSize *
2036 ((packing->RowLength + bw - 1) / bw);
2037 }
2038
2039 store->SkipBytes += packing->SkipPixels * packing->CompressedBlockSize / bw;
2040 }
2041
2042 if (dims > 1 && packing->CompressedBlockHeight &&
2043 packing->CompressedBlockSize) {
2044
2045 bh = packing->CompressedBlockHeight;
2046
2047 store->SkipBytes += packing->SkipRows * store->TotalBytesPerRow / bh;
2048 store->CopyRowsPerSlice = (height + bh - 1) / bh; /* rows in blocks */
2049
2050 if (packing->ImageHeight) {
2051 store->TotalRowsPerSlice = (packing->ImageHeight + bh - 1) / bh;
2052 }
2053 }
2054
2055 if (dims > 2 && packing->CompressedBlockDepth &&
2056 packing->CompressedBlockSize) {
2057
2058 int bd = packing->CompressedBlockDepth;
2059
2060 store->SkipBytes += packing->SkipImages * store->TotalBytesPerRow *
2061 store->TotalRowsPerSlice / bd;
2062 }
2063 }
2064
2065
2066 /**
2067 * Fallback for Driver.CompressedTexSubImage()
2068 */
2069 void
2070 _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
2071 struct gl_texture_image *texImage,
2072 GLint xoffset, GLint yoffset, GLint zoffset,
2073 GLsizei width, GLsizei height, GLsizei depth,
2074 GLenum format,
2075 GLsizei imageSize, const GLvoid *data)
2076 {
2077 struct compressed_pixelstore store;
2078 GLint dstRowStride;
2079 GLint i, slice;
2080 GLubyte *dstMap;
2081 const GLubyte *src;
2082
2083 if (dims == 1) {
2084 _mesa_problem(ctx, "Unexpected 1D compressed texsubimage call");
2085 return;
2086 }
2087
2088 _mesa_compute_compressed_pixelstore(dims, texImage->TexFormat,
2089 width, height, depth,
2090 &ctx->Unpack, &store);
2091
2092 /* get pointer to src pixels (may be in a pbo which we'll map here) */
2093 data = _mesa_validate_pbo_compressed_teximage(ctx, dims, imageSize, data,
2094 &ctx->Unpack,
2095 "glCompressedTexSubImage");
2096 if (!data)
2097 return;
2098
2099 src = (const GLubyte *) data + store.SkipBytes;
2100
2101 for (slice = 0; slice < store.CopySlices; slice++) {
2102 /* Map dest texture buffer */
2103 ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset,
2104 xoffset, yoffset, width, height,
2105 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
2106 &dstMap, &dstRowStride);
2107
2108 if (dstMap) {
2109
2110 /* copy rows of blocks */
2111 for (i = 0; i < store.CopyRowsPerSlice; i++) {
2112 memcpy(dstMap, src, store.CopyBytesPerRow);
2113 dstMap += dstRowStride;
2114 src += store.TotalBytesPerRow;
2115 }
2116
2117 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset);
2118
2119 /* advance to next slice */
2120 src += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice);
2121 }
2122 else {
2123 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD",
2124 dims);
2125 }
2126 }
2127
2128 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
2129 }