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