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