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