mesa: Remove _mesa_make_temp_ubyte_image
[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 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
225 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
226 static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE };
227
228
229 /**
230 * Teximage storage routine for when a simple memcpy will do.
231 * No pixel transfer operations or special texel encodings allowed.
232 * 1D, 2D and 3D images supported.
233 */
234 static void
235 memcpy_texture(struct gl_context *ctx,
236 GLuint dimensions,
237 mesa_format dstFormat,
238 GLint dstRowStride,
239 GLubyte **dstSlices,
240 GLint srcWidth, GLint srcHeight, GLint srcDepth,
241 GLenum srcFormat, GLenum srcType,
242 const GLvoid *srcAddr,
243 const struct gl_pixelstore_attrib *srcPacking)
244 {
245 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
246 srcFormat, srcType);
247 const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
248 srcWidth, srcHeight, srcFormat, srcType);
249 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
250 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
251 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
252 const GLint bytesPerRow = srcWidth * texelBytes;
253
254 if (dstRowStride == srcRowStride &&
255 dstRowStride == bytesPerRow) {
256 /* memcpy image by image */
257 GLint img;
258 for (img = 0; img < srcDepth; img++) {
259 GLubyte *dstImage = dstSlices[img];
260 memcpy(dstImage, srcImage, bytesPerRow * srcHeight);
261 srcImage += srcImageStride;
262 }
263 }
264 else {
265 /* memcpy row by row */
266 GLint img, row;
267 for (img = 0; img < srcDepth; img++) {
268 const GLubyte *srcRow = srcImage;
269 GLubyte *dstRow = dstSlices[img];
270 for (row = 0; row < srcHeight; row++) {
271 memcpy(dstRow, srcRow, bytesPerRow);
272 dstRow += dstRowStride;
273 srcRow += srcRowStride;
274 }
275 srcImage += srcImageStride;
276 }
277 }
278 }
279
280
281 /**
282 * Store a 32-bit integer or float depth component texture image.
283 */
284 static GLboolean
285 _mesa_texstore_z32(TEXSTORE_PARAMS)
286 {
287 const GLuint depthScale = 0xffffffff;
288 GLenum dstType;
289 (void) dims;
290 ASSERT(dstFormat == MESA_FORMAT_Z_UNORM32 ||
291 dstFormat == MESA_FORMAT_Z_FLOAT32);
292 ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
293
294 if (dstFormat == MESA_FORMAT_Z_UNORM32)
295 dstType = GL_UNSIGNED_INT;
296 else
297 dstType = GL_FLOAT;
298
299 {
300 /* general path */
301 GLint img, row;
302 for (img = 0; img < srcDepth; img++) {
303 GLubyte *dstRow = dstSlices[img];
304 for (row = 0; row < srcHeight; row++) {
305 const GLvoid *src = _mesa_image_address(dims, srcPacking,
306 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
307 _mesa_unpack_depth_span(ctx, srcWidth,
308 dstType, dstRow,
309 depthScale, srcType, src, srcPacking);
310 dstRow += dstRowStride;
311 }
312 }
313 }
314 return GL_TRUE;
315 }
316
317
318 /**
319 * Store a 24-bit integer depth component texture image.
320 */
321 static GLboolean
322 _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
323 {
324 const GLuint depthScale = 0xffffff;
325
326 (void) dims;
327 ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
328
329 {
330 /* general path */
331 GLint img, row;
332 for (img = 0; img < srcDepth; img++) {
333 GLubyte *dstRow = dstSlices[img];
334 for (row = 0; row < srcHeight; row++) {
335 const GLvoid *src = _mesa_image_address(dims, srcPacking,
336 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
337 _mesa_unpack_depth_span(ctx, srcWidth,
338 GL_UNSIGNED_INT, (GLuint *) dstRow,
339 depthScale, srcType, src, srcPacking);
340 dstRow += dstRowStride;
341 }
342 }
343 }
344 return GL_TRUE;
345 }
346
347
348 /**
349 * Store a 24-bit integer depth component texture image.
350 */
351 static GLboolean
352 _mesa_texstore_z24_x8(TEXSTORE_PARAMS)
353 {
354 const GLuint depthScale = 0xffffff;
355
356 (void) dims;
357 ASSERT(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
358
359 {
360 /* general path */
361 GLint img, row;
362 for (img = 0; img < srcDepth; img++) {
363 GLubyte *dstRow = dstSlices[img];
364 for (row = 0; row < srcHeight; row++) {
365 const GLvoid *src = _mesa_image_address(dims, srcPacking,
366 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
367 GLuint *dst = (GLuint *) dstRow;
368 GLint i;
369 _mesa_unpack_depth_span(ctx, srcWidth,
370 GL_UNSIGNED_INT, dst,
371 depthScale, srcType, src, srcPacking);
372 for (i = 0; i < srcWidth; i++)
373 dst[i] <<= 8;
374 dstRow += dstRowStride;
375 }
376 }
377 }
378 return GL_TRUE;
379 }
380
381
382 /**
383 * Store a 16-bit integer depth component texture image.
384 */
385 static GLboolean
386 _mesa_texstore_z16(TEXSTORE_PARAMS)
387 {
388 const GLuint depthScale = 0xffff;
389 (void) dims;
390 ASSERT(dstFormat == MESA_FORMAT_Z_UNORM16);
391 ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
392
393 {
394 /* general path */
395 GLint img, row;
396 for (img = 0; img < srcDepth; img++) {
397 GLubyte *dstRow = dstSlices[img];
398 for (row = 0; row < srcHeight; row++) {
399 const GLvoid *src = _mesa_image_address(dims, srcPacking,
400 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
401 GLushort *dst16 = (GLushort *) dstRow;
402 _mesa_unpack_depth_span(ctx, srcWidth,
403 GL_UNSIGNED_SHORT, dst16, depthScale,
404 srcType, src, srcPacking);
405 dstRow += dstRowStride;
406 }
407 }
408 }
409 return GL_TRUE;
410 }
411
412
413 /**
414 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
415 */
416 static GLboolean
417 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
418 {
419 const GLboolean littleEndian = _mesa_little_endian();
420
421 (void) ctx; (void) dims; (void) baseInternalFormat;
422
423 ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
424 (dstFormat == MESA_FORMAT_YCBCR_REV));
425 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
426 ASSERT(ctx->Extensions.MESA_ycbcr_texture);
427 ASSERT(srcFormat == GL_YCBCR_MESA);
428 ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
429 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
430 ASSERT(baseInternalFormat == GL_YCBCR_MESA);
431
432 /* always just memcpy since no pixel transfer ops apply */
433 memcpy_texture(ctx, dims,
434 dstFormat,
435 dstRowStride, dstSlices,
436 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
437 srcAddr, srcPacking);
438
439 /* Check if we need byte swapping */
440 /* XXX the logic here _might_ be wrong */
441 if (srcPacking->SwapBytes ^
442 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
443 (dstFormat == MESA_FORMAT_YCBCR_REV) ^
444 !littleEndian) {
445 GLint img, row;
446 for (img = 0; img < srcDepth; img++) {
447 GLubyte *dstRow = dstSlices[img];
448 for (row = 0; row < srcHeight; row++) {
449 _mesa_swap2((GLushort *) dstRow, srcWidth);
450 dstRow += dstRowStride;
451 }
452 }
453 }
454 return GL_TRUE;
455 }
456
457
458 /**
459 * Store a combined depth/stencil texture image.
460 */
461 static GLboolean
462 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
463 {
464 const GLuint depthScale = 0xffffff;
465 const GLint srcRowStride
466 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
467 GLint img, row;
468 GLuint *depth = malloc(srcWidth * sizeof(GLuint));
469 GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
470
471 ASSERT(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM);
472 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
473 srcFormat == GL_DEPTH_COMPONENT ||
474 srcFormat == GL_STENCIL_INDEX);
475 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
476 srcType == GL_UNSIGNED_INT_24_8_EXT ||
477 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
478
479 if (!depth || !stencil) {
480 free(depth);
481 free(stencil);
482 return GL_FALSE;
483 }
484
485 /* In case we only upload depth we need to preserve the stencil */
486 for (img = 0; img < srcDepth; img++) {
487 GLuint *dstRow = (GLuint *) dstSlices[img];
488 const GLubyte *src
489 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
490 srcWidth, srcHeight,
491 srcFormat, srcType,
492 img, 0, 0);
493 for (row = 0; row < srcHeight; row++) {
494 GLint i;
495 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
496
497 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
498 keepstencil = GL_TRUE;
499 }
500 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
501 keepdepth = GL_TRUE;
502 }
503
504 if (keepdepth == GL_FALSE)
505 /* the 24 depth bits will be in the low position: */
506 _mesa_unpack_depth_span(ctx, srcWidth,
507 GL_UNSIGNED_INT, /* dst type */
508 keepstencil ? depth : dstRow, /* dst addr */
509 depthScale,
510 srcType, src, srcPacking);
511
512 if (keepstencil == GL_FALSE)
513 /* get the 8-bit stencil values */
514 _mesa_unpack_stencil_span(ctx, srcWidth,
515 GL_UNSIGNED_BYTE, /* dst type */
516 stencil, /* dst addr */
517 srcType, src, srcPacking,
518 ctx->_ImageTransferState);
519
520 for (i = 0; i < srcWidth; i++) {
521 if (keepstencil)
522 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
523 else
524 dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
525 }
526 src += srcRowStride;
527 dstRow += dstRowStride / sizeof(GLuint);
528 }
529 }
530
531 free(depth);
532 free(stencil);
533 return GL_TRUE;
534 }
535
536
537 /**
538 * Store a combined depth/stencil texture image.
539 */
540 static GLboolean
541 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
542 {
543 const GLuint depthScale = 0xffffff;
544 const GLint srcRowStride
545 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
546 GLint img, row;
547 GLuint *depth;
548 GLubyte *stencil;
549
550 ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
551 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
552 srcFormat == GL_DEPTH_COMPONENT ||
553 srcFormat == GL_STENCIL_INDEX);
554 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
555 srcType == GL_UNSIGNED_INT_24_8_EXT ||
556 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
557
558 depth = malloc(srcWidth * sizeof(GLuint));
559 stencil = malloc(srcWidth * sizeof(GLubyte));
560
561 if (!depth || !stencil) {
562 free(depth);
563 free(stencil);
564 return GL_FALSE;
565 }
566
567 for (img = 0; img < srcDepth; img++) {
568 GLuint *dstRow = (GLuint *) dstSlices[img];
569 const GLubyte *src
570 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
571 srcWidth, srcHeight,
572 srcFormat, srcType,
573 img, 0, 0);
574 for (row = 0; row < srcHeight; row++) {
575 GLint i;
576 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
577
578 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
579 keepstencil = GL_TRUE;
580 }
581 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
582 keepdepth = GL_TRUE;
583 }
584
585 if (keepdepth == GL_FALSE)
586 /* the 24 depth bits will be in the low position: */
587 _mesa_unpack_depth_span(ctx, srcWidth,
588 GL_UNSIGNED_INT, /* dst type */
589 keepstencil ? depth : dstRow, /* dst addr */
590 depthScale,
591 srcType, src, srcPacking);
592
593 if (keepstencil == GL_FALSE)
594 /* get the 8-bit stencil values */
595 _mesa_unpack_stencil_span(ctx, srcWidth,
596 GL_UNSIGNED_BYTE, /* dst type */
597 stencil, /* dst addr */
598 srcType, src, srcPacking,
599 ctx->_ImageTransferState);
600
601 /* merge stencil values into depth values */
602 for (i = 0; i < srcWidth; i++) {
603 if (keepstencil)
604 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
605 else
606 dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
607
608 }
609 src += srcRowStride;
610 dstRow += dstRowStride / sizeof(GLuint);
611 }
612 }
613
614 free(depth);
615 free(stencil);
616
617 return GL_TRUE;
618 }
619
620
621 /**
622 * Store simple 8-bit/value stencil texture data.
623 */
624 static GLboolean
625 _mesa_texstore_s8(TEXSTORE_PARAMS)
626 {
627 ASSERT(dstFormat == MESA_FORMAT_S_UINT8);
628 ASSERT(srcFormat == GL_STENCIL_INDEX);
629
630 {
631 const GLint srcRowStride
632 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
633 GLint img, row;
634 GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
635
636 if (!stencil)
637 return GL_FALSE;
638
639 for (img = 0; img < srcDepth; img++) {
640 GLubyte *dstRow = dstSlices[img];
641 const GLubyte *src
642 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
643 srcWidth, srcHeight,
644 srcFormat, srcType,
645 img, 0, 0);
646 for (row = 0; row < srcHeight; row++) {
647 GLint i;
648
649 /* get the 8-bit stencil values */
650 _mesa_unpack_stencil_span(ctx, srcWidth,
651 GL_UNSIGNED_BYTE, /* dst type */
652 stencil, /* dst addr */
653 srcType, src, srcPacking,
654 ctx->_ImageTransferState);
655 /* merge stencil values into depth values */
656 for (i = 0; i < srcWidth; i++)
657 dstRow[i] = stencil[i];
658
659 src += srcRowStride;
660 dstRow += dstRowStride / sizeof(GLubyte);
661 }
662 }
663
664 free(stencil);
665 }
666
667 return GL_TRUE;
668 }
669
670
671 static GLboolean
672 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
673 {
674 GLint img, row;
675 const GLint srcRowStride
676 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
677 / sizeof(uint64_t);
678
679 ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
680 ASSERT(srcFormat == GL_DEPTH_STENCIL ||
681 srcFormat == GL_DEPTH_COMPONENT ||
682 srcFormat == GL_STENCIL_INDEX);
683 ASSERT(srcFormat != GL_DEPTH_STENCIL ||
684 srcType == GL_UNSIGNED_INT_24_8 ||
685 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
686
687 /* In case we only upload depth we need to preserve the stencil */
688 for (img = 0; img < srcDepth; img++) {
689 uint64_t *dstRow = (uint64_t *) dstSlices[img];
690 const uint64_t *src
691 = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
692 srcWidth, srcHeight,
693 srcFormat, srcType,
694 img, 0, 0);
695 for (row = 0; row < srcHeight; row++) {
696 /* The unpack functions with:
697 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
698 * only write their own dword, so the other dword (stencil
699 * or depth) is preserved. */
700 if (srcFormat != GL_STENCIL_INDEX)
701 _mesa_unpack_depth_span(ctx, srcWidth,
702 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
703 dstRow, /* dst addr */
704 ~0U, srcType, src, srcPacking);
705
706 if (srcFormat != GL_DEPTH_COMPONENT)
707 _mesa_unpack_stencil_span(ctx, srcWidth,
708 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
709 dstRow, /* dst addr */
710 srcType, src, srcPacking,
711 ctx->_ImageTransferState);
712
713 src += srcRowStride;
714 dstRow += dstRowStride / sizeof(uint64_t);
715 }
716 }
717 return GL_TRUE;
718 }
719
720 static GLboolean
721 texstore_depth_stencil(TEXSTORE_PARAMS)
722 {
723 static StoreTexImageFunc table[MESA_FORMAT_COUNT];
724 static GLboolean initialized = GL_FALSE;
725
726 if (!initialized) {
727 memset(table, 0, sizeof table);
728
729 table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8;
730 table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24;
731 table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16;
732 table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_x8_z24;
733 table[MESA_FORMAT_X8_UINT_Z24_UNORM] = _mesa_texstore_z24_x8;
734 table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32;
735 table[MESA_FORMAT_S_UINT8] = _mesa_texstore_s8;
736 table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32;
737 table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8;
738
739 initialized = GL_TRUE;
740 }
741
742 ASSERT(table[dstFormat]);
743 return table[dstFormat](ctx, dims, baseInternalFormat,
744 dstFormat, dstRowStride, dstSlices,
745 srcWidth, srcHeight, srcDepth,
746 srcFormat, srcType, srcAddr, srcPacking);
747 }
748
749 static GLboolean
750 texstore_compressed(TEXSTORE_PARAMS)
751 {
752 static StoreTexImageFunc table[MESA_FORMAT_COUNT];
753 static GLboolean initialized = GL_FALSE;
754
755 if (!initialized) {
756 memset(table, 0, sizeof table);
757
758 table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
759 table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
760 table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
761 table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
762 table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
763 table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
764 table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
765 table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
766 table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
767 table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
768 table[MESA_FORMAT_R_RGTC1_UNORM] = _mesa_texstore_red_rgtc1;
769 table[MESA_FORMAT_R_RGTC1_SNORM] = _mesa_texstore_signed_red_rgtc1;
770 table[MESA_FORMAT_RG_RGTC2_UNORM] = _mesa_texstore_rg_rgtc2;
771 table[MESA_FORMAT_RG_RGTC2_SNORM] = _mesa_texstore_signed_rg_rgtc2;
772 table[MESA_FORMAT_L_LATC1_UNORM] = _mesa_texstore_red_rgtc1;
773 table[MESA_FORMAT_L_LATC1_SNORM] = _mesa_texstore_signed_red_rgtc1;
774 table[MESA_FORMAT_LA_LATC2_UNORM] = _mesa_texstore_rg_rgtc2;
775 table[MESA_FORMAT_LA_LATC2_SNORM] = _mesa_texstore_signed_rg_rgtc2;
776 table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
777 table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8;
778 table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8;
779 table[MESA_FORMAT_ETC2_RGBA8_EAC] = _mesa_texstore_etc2_rgba8_eac;
780 table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = _mesa_texstore_etc2_srgb8_alpha8_eac;
781 table[MESA_FORMAT_ETC2_R11_EAC] = _mesa_texstore_etc2_r11_eac;
782 table[MESA_FORMAT_ETC2_RG11_EAC] = _mesa_texstore_etc2_rg11_eac;
783 table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = _mesa_texstore_etc2_signed_r11_eac;
784 table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = _mesa_texstore_etc2_signed_rg11_eac;
785 table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] =
786 _mesa_texstore_etc2_rgb8_punchthrough_alpha1;
787 table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] =
788 _mesa_texstore_etc2_srgb8_punchthrough_alpha1;
789
790 table[MESA_FORMAT_BPTC_RGBA_UNORM] =
791 _mesa_texstore_bptc_rgba_unorm;
792 table[MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM] =
793 _mesa_texstore_bptc_rgba_unorm;
794 table[MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT] =
795 _mesa_texstore_bptc_rgb_signed_float;
796 table[MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT] =
797 _mesa_texstore_bptc_rgb_unsigned_float;
798
799 initialized = GL_TRUE;
800 }
801
802 ASSERT(table[dstFormat]);
803 return table[dstFormat](ctx, dims, baseInternalFormat,
804 dstFormat, dstRowStride, dstSlices,
805 srcWidth, srcHeight, srcDepth,
806 srcFormat, srcType, srcAddr, srcPacking);
807 }
808
809 static GLboolean
810 texstore_rgba(TEXSTORE_PARAMS)
811 {
812 void *tempImage = NULL;
813 int srcRowStride, img;
814 GLubyte *src;
815 uint32_t srcMesaFormat;
816 uint8_t rebaseSwizzle[4];
817 bool needRebase;
818
819 /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case
820 * and _mesa_format_convert does not support it. In this case the we only
821 * allow conversions between YCBCR formats and it is mostly a memcpy.
822 */
823 if (dstFormat == MESA_FORMAT_YCBCR || dstFormat == MESA_FORMAT_YCBCR_REV) {
824 return _mesa_texstore_ycbcr(ctx, dims, baseInternalFormat,
825 dstFormat, dstRowStride, dstSlices,
826 srcWidth, srcHeight, srcDepth,
827 srcFormat, srcType, srcAddr,
828 srcPacking);
829 }
830
831 /* We have to deal with GL_COLOR_INDEX manually because
832 * _mesa_format_convert does not handle this format. So what we do here is
833 * convert it to RGBA ubyte first and then convert from that to dst as usual.
834 */
835 if (srcFormat == GL_COLOR_INDEX) {
836 /* Notice that this will already handle byte swapping if necessary */
837 tempImage =
838 _mesa_unpack_color_index_to_rgba_ubyte(ctx, dims,
839 srcAddr, srcFormat, srcType,
840 srcWidth, srcHeight, srcDepth,
841 srcPacking,
842 ctx->_ImageTransferState);
843 if (!tempImage)
844 return GL_FALSE;
845
846 /* Now we only have to adjust our src info for a conversion from
847 * the RGBA ubyte and then we continue as usual.
848 */
849 srcAddr = tempImage;
850 srcFormat = GL_RGBA;
851 srcType = GL_UNSIGNED_BYTE;
852 } else if (srcPacking->SwapBytes) {
853 /* We have to handle byte-swapping scenarios before calling
854 * _mesa_format_convert
855 */
856 GLint swapSize = _mesa_sizeof_packed_type(srcType);
857 if (swapSize == 2 || swapSize == 4) {
858 int components = _mesa_components_in_format(srcFormat);
859 int elementCount = srcWidth * srcHeight * components;
860 tempImage = malloc(elementCount * swapSize);
861 if (!tempImage)
862 return GL_FALSE;
863 if (swapSize == 2)
864 _mesa_swap2_copy(tempImage, (GLushort *) srcAddr, elementCount);
865 else
866 _mesa_swap4_copy(tempImage, (GLuint *) srcAddr, elementCount);
867 srcAddr = tempImage;
868 }
869 }
870
871 srcRowStride =
872 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
873
874 src = (GLubyte *)
875 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
876 srcFormat, srcType, 0, 0, 0);
877
878 srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType);
879 dstFormat = _mesa_get_srgb_format_linear(dstFormat);
880
881 if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) {
882 needRebase =
883 _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat,
884 rebaseSwizzle);
885 } else {
886 needRebase = false;
887 }
888
889 for (img = 0; img < srcDepth; img++) {
890 _mesa_format_convert(dstSlices[img], dstFormat, dstRowStride,
891 src, srcMesaFormat, srcRowStride,
892 srcWidth, srcHeight,
893 needRebase ? rebaseSwizzle : NULL);
894 src += srcHeight * srcRowStride;
895 }
896
897 free(tempImage);
898
899 return GL_TRUE;
900 }
901
902 GLboolean
903 _mesa_texstore_needs_transfer_ops(struct gl_context *ctx,
904 GLenum baseInternalFormat,
905 mesa_format dstFormat)
906 {
907 GLenum dstType;
908
909 /* There are different rules depending on the base format. */
910 switch (baseInternalFormat) {
911 case GL_DEPTH_COMPONENT:
912 case GL_DEPTH_STENCIL:
913 return ctx->Pixel.DepthScale != 1.0f ||
914 ctx->Pixel.DepthBias != 0.0f;
915
916 case GL_STENCIL_INDEX:
917 return GL_FALSE;
918
919 default:
920 /* Color formats.
921 * Pixel transfer ops (scale, bias, table lookup) do not apply
922 * to integer formats.
923 */
924 dstType = _mesa_get_format_datatype(dstFormat);
925
926 return dstType != GL_INT && dstType != GL_UNSIGNED_INT &&
927 ctx->_ImageTransferState;
928 }
929 }
930
931
932 GLboolean
933 _mesa_texstore_can_use_memcpy(struct gl_context *ctx,
934 GLenum baseInternalFormat, mesa_format dstFormat,
935 GLenum srcFormat, GLenum srcType,
936 const struct gl_pixelstore_attrib *srcPacking)
937 {
938 if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
939 return GL_FALSE;
940 }
941
942 /* The base internal format and the base Mesa format must match. */
943 if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) {
944 return GL_FALSE;
945 }
946
947 /* The Mesa format must match the input format and type. */
948 if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
949 srcPacking->SwapBytes)) {
950 return GL_FALSE;
951 }
952
953 /* Depth texture data needs clamping in following cases:
954 * - Floating point dstFormat with signed srcType: clamp to [0.0, 1.0].
955 * - Fixed point dstFormat with signed srcType: clamp to [0, 2^n -1].
956 *
957 * All the cases except one (float dstFormat with float srcType) are ruled
958 * out by _mesa_format_matches_format_and_type() check above. Handle the
959 * remaining case here.
960 */
961 if ((baseInternalFormat == GL_DEPTH_COMPONENT ||
962 baseInternalFormat == GL_DEPTH_STENCIL) &&
963 (srcType == GL_FLOAT ||
964 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)) {
965 return GL_FALSE;
966 }
967
968 return GL_TRUE;
969 }
970
971 static GLboolean
972 _mesa_texstore_memcpy(TEXSTORE_PARAMS)
973 {
974 if (!_mesa_texstore_can_use_memcpy(ctx, baseInternalFormat, dstFormat,
975 srcFormat, srcType, srcPacking)) {
976 return GL_FALSE;
977 }
978
979 memcpy_texture(ctx, dims,
980 dstFormat,
981 dstRowStride, dstSlices,
982 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
983 srcAddr, srcPacking);
984 return GL_TRUE;
985 }
986 /**
987 * Store user data into texture memory.
988 * Called via glTex[Sub]Image1/2/3D()
989 * \return GL_TRUE for success, GL_FALSE for failure (out of memory).
990 */
991 GLboolean
992 _mesa_texstore(TEXSTORE_PARAMS)
993 {
994 if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat,
995 dstFormat,
996 dstRowStride, dstSlices,
997 srcWidth, srcHeight, srcDepth,
998 srcFormat, srcType, srcAddr, srcPacking)) {
999 return GL_TRUE;
1000 }
1001
1002 if (_mesa_is_depth_or_stencil_format(baseInternalFormat)) {
1003 return texstore_depth_stencil(ctx, dims, baseInternalFormat,
1004 dstFormat, dstRowStride, dstSlices,
1005 srcWidth, srcHeight, srcDepth,
1006 srcFormat, srcType, srcAddr, srcPacking);
1007 } else if (_mesa_is_format_compressed(dstFormat)) {
1008 return texstore_compressed(ctx, dims, baseInternalFormat,
1009 dstFormat, dstRowStride, dstSlices,
1010 srcWidth, srcHeight, srcDepth,
1011 srcFormat, srcType, srcAddr, srcPacking);
1012 } else {
1013 return texstore_rgba(ctx, dims, baseInternalFormat,
1014 dstFormat, dstRowStride, dstSlices,
1015 srcWidth, srcHeight, srcDepth,
1016 srcFormat, srcType, srcAddr, srcPacking);
1017 }
1018 }
1019
1020
1021 /**
1022 * Normally, we'll only _write_ texel data to a texture when we map it.
1023 * But if the user is providing depth or stencil values and the texture
1024 * image is a combined depth/stencil format, we'll actually read from
1025 * the texture buffer too (in order to insert the depth or stencil values.
1026 * \param userFormat the user-provided image format
1027 * \param texFormat the destination texture format
1028 */
1029 static GLbitfield
1030 get_read_write_mode(GLenum userFormat, mesa_format texFormat)
1031 {
1032 if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
1033 && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
1034 return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
1035 else
1036 return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
1037 }
1038
1039
1040 /**
1041 * Helper function for storing 1D, 2D, 3D whole and subimages into texture
1042 * memory.
1043 * The source of the image data may be user memory or a PBO. In the later
1044 * case, we'll map the PBO, copy from it, then unmap it.
1045 */
1046 static void
1047 store_texsubimage(struct gl_context *ctx,
1048 struct gl_texture_image *texImage,
1049 GLint xoffset, GLint yoffset, GLint zoffset,
1050 GLint width, GLint height, GLint depth,
1051 GLenum format, GLenum type, const GLvoid *pixels,
1052 const struct gl_pixelstore_attrib *packing,
1053 const char *caller)
1054
1055 {
1056 const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat);
1057 const GLenum target = texImage->TexObject->Target;
1058 GLboolean success = GL_FALSE;
1059 GLuint dims, slice, numSlices = 1, sliceOffset = 0;
1060 GLint srcImageStride = 0;
1061 const GLubyte *src;
1062
1063 assert(xoffset + width <= texImage->Width);
1064 assert(yoffset + height <= texImage->Height);
1065 assert(zoffset + depth <= texImage->Depth);
1066
1067 switch (target) {
1068 case GL_TEXTURE_1D:
1069 dims = 1;
1070 break;
1071 case GL_TEXTURE_2D_ARRAY:
1072 case GL_TEXTURE_CUBE_MAP_ARRAY:
1073 case GL_TEXTURE_3D:
1074 dims = 3;
1075 break;
1076 default:
1077 dims = 2;
1078 }
1079
1080 /* get pointer to src pixels (may be in a pbo which we'll map here) */
1081 src = (const GLubyte *)
1082 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
1083 format, type, pixels, packing, caller);
1084 if (!src)
1085 return;
1086
1087 /* compute slice info (and do some sanity checks) */
1088 switch (target) {
1089 case GL_TEXTURE_2D:
1090 case GL_TEXTURE_RECTANGLE:
1091 case GL_TEXTURE_CUBE_MAP:
1092 case GL_TEXTURE_EXTERNAL_OES:
1093 /* one image slice, nothing special needs to be done */
1094 break;
1095 case GL_TEXTURE_1D:
1096 assert(height == 1);
1097 assert(depth == 1);
1098 assert(yoffset == 0);
1099 assert(zoffset == 0);
1100 break;
1101 case GL_TEXTURE_1D_ARRAY:
1102 assert(depth == 1);
1103 assert(zoffset == 0);
1104 numSlices = height;
1105 sliceOffset = yoffset;
1106 height = 1;
1107 yoffset = 0;
1108 srcImageStride = _mesa_image_row_stride(packing, width, format, type);
1109 break;
1110 case GL_TEXTURE_2D_ARRAY:
1111 numSlices = depth;
1112 sliceOffset = zoffset;
1113 depth = 1;
1114 zoffset = 0;
1115 srcImageStride = _mesa_image_image_stride(packing, width, height,
1116 format, type);
1117 break;
1118 case GL_TEXTURE_3D:
1119 /* we'll store 3D images as a series of slices */
1120 numSlices = depth;
1121 sliceOffset = zoffset;
1122 srcImageStride = _mesa_image_image_stride(packing, width, height,
1123 format, type);
1124 break;
1125 case GL_TEXTURE_CUBE_MAP_ARRAY:
1126 numSlices = depth;
1127 sliceOffset = zoffset;
1128 srcImageStride = _mesa_image_image_stride(packing, width, height,
1129 format, type);
1130 break;
1131 default:
1132 _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
1133 return;
1134 }
1135
1136 assert(numSlices == 1 || srcImageStride != 0);
1137
1138 for (slice = 0; slice < numSlices; slice++) {
1139 GLubyte *dstMap;
1140 GLint dstRowStride;
1141
1142 ctx->Driver.MapTextureImage(ctx, texImage,
1143 slice + sliceOffset,
1144 xoffset, yoffset, width, height,
1145 mapMode, &dstMap, &dstRowStride);
1146 if (dstMap) {
1147 /* Note: we're only storing a 2D (or 1D) slice at a time but we need
1148 * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
1149 * used for 3D images.
1150 */
1151 success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
1152 texImage->TexFormat,
1153 dstRowStride,
1154 &dstMap,
1155 width, height, 1, /* w, h, d */
1156 format, type, src, packing);
1157
1158 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
1159 }
1160
1161 src += srcImageStride;
1162
1163 if (!success)
1164 break;
1165 }
1166
1167 if (!success)
1168 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
1169
1170 _mesa_unmap_teximage_pbo(ctx, packing);
1171 }
1172
1173
1174
1175 /**
1176 * Fallback code for ctx->Driver.TexImage().
1177 * Basically, allocate storage for the texture image, then copy the
1178 * user's image into it.
1179 */
1180 void
1181 _mesa_store_teximage(struct gl_context *ctx,
1182 GLuint dims,
1183 struct gl_texture_image *texImage,
1184 GLenum format, GLenum type, const GLvoid *pixels,
1185 const struct gl_pixelstore_attrib *packing)
1186 {
1187 assert(dims == 1 || dims == 2 || dims == 3);
1188
1189 if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
1190 return;
1191
1192 /* allocate storage for texture data */
1193 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
1194 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
1195 return;
1196 }
1197
1198 store_texsubimage(ctx, texImage,
1199 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth,
1200 format, type, pixels, packing, "glTexImage");
1201 }
1202
1203
1204 /*
1205 * Fallback for Driver.TexSubImage().
1206 */
1207 void
1208 _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims,
1209 struct gl_texture_image *texImage,
1210 GLint xoffset, GLint yoffset, GLint zoffset,
1211 GLint width, GLint height, GLint depth,
1212 GLenum format, GLenum type, const void *pixels,
1213 const struct gl_pixelstore_attrib *packing)
1214 {
1215 store_texsubimage(ctx, texImage,
1216 xoffset, yoffset, zoffset, width, height, depth,
1217 format, type, pixels, packing, "glTexSubImage");
1218 }
1219
1220 static void
1221 clear_image_to_zero(GLubyte *dstMap, GLint dstRowStride,
1222 GLsizei width, GLsizei height,
1223 GLsizei clearValueSize)
1224 {
1225 GLsizei y;
1226
1227 for (y = 0; y < height; y++) {
1228 memset(dstMap, 0, clearValueSize * width);
1229 dstMap += dstRowStride;
1230 }
1231 }
1232
1233 static void
1234 clear_image_to_value(GLubyte *dstMap, GLint dstRowStride,
1235 GLsizei width, GLsizei height,
1236 const GLvoid *clearValue,
1237 GLsizei clearValueSize)
1238 {
1239 GLsizei y, x;
1240
1241 for (y = 0; y < height; y++) {
1242 for (x = 0; x < width; x++) {
1243 memcpy(dstMap, clearValue, clearValueSize);
1244 dstMap += clearValueSize;
1245 }
1246 dstMap += dstRowStride - clearValueSize * width;
1247 }
1248 }
1249
1250 /*
1251 * Fallback for Driver.ClearTexSubImage().
1252 */
1253 void
1254 _mesa_store_cleartexsubimage(struct gl_context *ctx,
1255 struct gl_texture_image *texImage,
1256 GLint xoffset, GLint yoffset, GLint zoffset,
1257 GLsizei width, GLsizei height, GLsizei depth,
1258 const GLvoid *clearValue)
1259 {
1260 GLubyte *dstMap;
1261 GLint dstRowStride;
1262 GLsizeiptr clearValueSize;
1263 GLsizei z;
1264
1265 clearValueSize = _mesa_get_format_bytes(texImage->TexFormat);
1266
1267 for (z = 0; z < depth; z++) {
1268 ctx->Driver.MapTextureImage(ctx, texImage,
1269 z + zoffset, xoffset, yoffset,
1270 width, height,
1271 GL_MAP_WRITE_BIT,
1272 &dstMap, &dstRowStride);
1273 if (dstMap == NULL) {
1274 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearTex*Image");
1275 return;
1276 }
1277
1278 if (clearValue) {
1279 clear_image_to_value(dstMap, dstRowStride,
1280 width, height,
1281 clearValue,
1282 clearValueSize);
1283 } else {
1284 clear_image_to_zero(dstMap, dstRowStride,
1285 width, height,
1286 clearValueSize);
1287 }
1288
1289 ctx->Driver.UnmapTextureImage(ctx, texImage, z + zoffset);
1290 }
1291 }
1292
1293 /**
1294 * Fallback for Driver.CompressedTexImage()
1295 */
1296 void
1297 _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
1298 struct gl_texture_image *texImage,
1299 GLsizei imageSize, const GLvoid *data)
1300 {
1301 /* only 2D and 3D compressed images are supported at this time */
1302 if (dims == 1) {
1303 _mesa_problem(ctx, "Unexpected glCompressedTexImage1D call");
1304 return;
1305 }
1306
1307 /* This is pretty simple, because unlike the general texstore path we don't
1308 * have to worry about the usual image unpacking or image transfer
1309 * operations.
1310 */
1311 ASSERT(texImage);
1312 ASSERT(texImage->Width > 0);
1313 ASSERT(texImage->Height > 0);
1314 ASSERT(texImage->Depth > 0);
1315
1316 /* allocate storage for texture data */
1317 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
1318 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage%uD", dims);
1319 return;
1320 }
1321
1322 _mesa_store_compressed_texsubimage(ctx, dims, texImage,
1323 0, 0, 0,
1324 texImage->Width, texImage->Height, texImage->Depth,
1325 texImage->TexFormat,
1326 imageSize, data);
1327 }
1328
1329
1330 /**
1331 * Compute compressed_pixelstore parameters for copying compressed
1332 * texture data.
1333 * \param dims number of texture image dimensions: 1, 2 or 3
1334 * \param texFormat the compressed texture format
1335 * \param width, height, depth size of image to copy
1336 * \param packing pixelstore parameters describing user-space image packing
1337 * \param store returns the compressed_pixelstore parameters
1338 */
1339 void
1340 _mesa_compute_compressed_pixelstore(GLuint dims, mesa_format texFormat,
1341 GLsizei width, GLsizei height,
1342 GLsizei depth,
1343 const struct gl_pixelstore_attrib *packing,
1344 struct compressed_pixelstore *store)
1345 {
1346 GLuint bw, bh;
1347
1348 _mesa_get_format_block_size(texFormat, &bw, &bh);
1349
1350 store->SkipBytes = 0;
1351 store->TotalBytesPerRow = store->CopyBytesPerRow =
1352 _mesa_format_row_stride(texFormat, width);
1353 store->TotalRowsPerSlice = store->CopyRowsPerSlice =
1354 (height + bh - 1) / bh;
1355 store->CopySlices = depth;
1356
1357 if (packing->CompressedBlockWidth &&
1358 packing->CompressedBlockSize) {
1359
1360 bw = packing->CompressedBlockWidth;
1361
1362 if (packing->RowLength) {
1363 store->TotalBytesPerRow = packing->CompressedBlockSize *
1364 ((packing->RowLength + bw - 1) / bw);
1365 }
1366
1367 store->SkipBytes += packing->SkipPixels * packing->CompressedBlockSize / bw;
1368 }
1369
1370 if (dims > 1 && packing->CompressedBlockHeight &&
1371 packing->CompressedBlockSize) {
1372
1373 bh = packing->CompressedBlockHeight;
1374
1375 store->SkipBytes += packing->SkipRows * store->TotalBytesPerRow / bh;
1376 store->CopyRowsPerSlice = (height + bh - 1) / bh; /* rows in blocks */
1377
1378 if (packing->ImageHeight) {
1379 store->TotalRowsPerSlice = (packing->ImageHeight + bh - 1) / bh;
1380 }
1381 }
1382
1383 if (dims > 2 && packing->CompressedBlockDepth &&
1384 packing->CompressedBlockSize) {
1385
1386 int bd = packing->CompressedBlockDepth;
1387
1388 store->SkipBytes += packing->SkipImages * store->TotalBytesPerRow *
1389 store->TotalRowsPerSlice / bd;
1390 }
1391 }
1392
1393
1394 /**
1395 * Fallback for Driver.CompressedTexSubImage()
1396 */
1397 void
1398 _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
1399 struct gl_texture_image *texImage,
1400 GLint xoffset, GLint yoffset, GLint zoffset,
1401 GLsizei width, GLsizei height, GLsizei depth,
1402 GLenum format,
1403 GLsizei imageSize, const GLvoid *data)
1404 {
1405 struct compressed_pixelstore store;
1406 GLint dstRowStride;
1407 GLint i, slice;
1408 GLubyte *dstMap;
1409 const GLubyte *src;
1410
1411 if (dims == 1) {
1412 _mesa_problem(ctx, "Unexpected 1D compressed texsubimage call");
1413 return;
1414 }
1415
1416 _mesa_compute_compressed_pixelstore(dims, texImage->TexFormat,
1417 width, height, depth,
1418 &ctx->Unpack, &store);
1419
1420 /* get pointer to src pixels (may be in a pbo which we'll map here) */
1421 data = _mesa_validate_pbo_compressed_teximage(ctx, dims, imageSize, data,
1422 &ctx->Unpack,
1423 "glCompressedTexSubImage");
1424 if (!data)
1425 return;
1426
1427 src = (const GLubyte *) data + store.SkipBytes;
1428
1429 for (slice = 0; slice < store.CopySlices; slice++) {
1430 /* Map dest texture buffer */
1431 ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset,
1432 xoffset, yoffset, width, height,
1433 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
1434 &dstMap, &dstRowStride);
1435
1436 if (dstMap) {
1437
1438 /* copy rows of blocks */
1439 for (i = 0; i < store.CopyRowsPerSlice; i++) {
1440 memcpy(dstMap, src, store.CopyBytesPerRow);
1441 dstMap += dstRowStride;
1442 src += store.TotalBytesPerRow;
1443 }
1444
1445 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset);
1446
1447 /* advance to next slice */
1448 src += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice);
1449 }
1450 else {
1451 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD",
1452 dims);
1453 }
1454 }
1455
1456 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
1457 }