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