Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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