Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**********************************************************
  2.  * Copyright 1998-2014 VMware, Inc.  All rights reserved.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person
  5.  * obtaining a copy of this software and associated documentation
  6.  * files (the "Software"), to deal in the Software without
  7.  * restriction, including without limitation the rights to use, copy,
  8.  * modify, merge, publish, distribute, sublicense, and/or sell copies
  9.  * of the Software, and to permit persons to whom the Software is
  10.  * furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice shall be
  13.  * included in all copies or substantial portions of the Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19.  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  *
  24.  **********************************************************/
  25.  
  26. /*
  27.  * svga3d_surfacedefs.h --
  28.  *
  29.  *       Surface/format/image helper code.
  30.  */
  31.  
  32. #include "svga3d_reg.h"
  33.  
  34. #define max_t(type, x, y)  ((x) > (y) ? (x) : (y))
  35.  
  36. /*
  37.  * enum svga3d_block_desc describes the active data channels in a block.
  38.  *
  39.  * There can be at-most four active channels in a block:
  40.  *    1. Red, bump W, luminance and depth are stored in the first channel.
  41.  *    2. Green, bump V and stencil are stored in the second channel.
  42.  *    3. Blue and bump U are stored in the third channel.
  43.  *    4. Alpha and bump Q are stored in the fourth channel.
  44.  *
  45.  * Block channels can be used to store compressed and buffer data:
  46.  *    1. For compressed formats, only the data channel is used and its size
  47.  *       is equal to that of a singular block in the compression scheme.
  48.  *    2. For buffer formats, only the data channel is used and its size is
  49.  *       exactly one byte in length.
  50.  *    3. In each case the bit depth represent the size of a singular block.
  51.  *
  52.  * Note: Compressed and IEEE formats do not use the bitMask structure.
  53.  */
  54.  
  55. enum svga3d_block_desc {
  56.         SVGA3DBLOCKDESC_NONE        = 0,         /* No channels are active */
  57.         SVGA3DBLOCKDESC_BLUE        = 1 << 0,    /* Block with red channel
  58.                                                     data */
  59.         SVGA3DBLOCKDESC_U           = 1 << 0,    /* Block with bump U channel
  60.                                                     data */
  61.         SVGA3DBLOCKDESC_UV_VIDEO    = 1 << 7,    /* Block with alternating video
  62.                                                     U and V */
  63.         SVGA3DBLOCKDESC_GREEN       = 1 << 1,    /* Block with green channel
  64.                                                     data */
  65.         SVGA3DBLOCKDESC_V           = 1 << 1,    /* Block with bump V channel
  66.                                                     data */
  67.         SVGA3DBLOCKDESC_STENCIL     = 1 << 1,    /* Block with a stencil
  68.                                                     channel */
  69.         SVGA3DBLOCKDESC_RED         = 1 << 2,    /* Block with blue channel
  70.                                                     data */
  71.         SVGA3DBLOCKDESC_W           = 1 << 2,    /* Block with bump W channel
  72.                                                     data */
  73.         SVGA3DBLOCKDESC_LUMINANCE   = 1 << 2,    /* Block with luminance channel
  74.                                                     data */
  75.         SVGA3DBLOCKDESC_Y           = 1 << 2,    /* Block with video luminance
  76.                                                     data */
  77.         SVGA3DBLOCKDESC_DEPTH       = 1 << 2,    /* Block with depth channel */
  78.         SVGA3DBLOCKDESC_ALPHA       = 1 << 3,    /* Block with an alpha
  79.                                                     channel */
  80.         SVGA3DBLOCKDESC_Q           = 1 << 3,    /* Block with bump Q channel
  81.                                                     data */
  82.         SVGA3DBLOCKDESC_BUFFER      = 1 << 4,    /* Block stores 1 byte of
  83.                                                     data */
  84.         SVGA3DBLOCKDESC_COMPRESSED  = 1 << 5,    /* Block stores n bytes of
  85.                                                     data depending on the
  86.                                                     compression method used */
  87.         SVGA3DBLOCKDESC_IEEE_FP     = 1 << 6,    /* Block stores data in an IEEE
  88.                                                     floating point
  89.                                                     representation in
  90.                                                     all channels */
  91.         SVGA3DBLOCKDESC_PLANAR_YUV  = 1 << 8,    /* Three separate blocks store
  92.                                                     data. */
  93.         SVGA3DBLOCKDESC_U_VIDEO     = 1 << 9,    /* Block with U video data */
  94.         SVGA3DBLOCKDESC_V_VIDEO     = 1 << 10,   /* Block with V video data */
  95.         SVGA3DBLOCKDESC_EXP         = 1 << 11,   /* Shared exponent */
  96.         SVGA3DBLOCKDESC_SRGB        = 1 << 12,   /* Data is in sRGB format */
  97.         SVGA3DBLOCKDESC_2PLANAR_YUV = 1 << 13,   /* 2 planes of Y, UV,
  98.                                                     e.g., NV12. */
  99.         SVGA3DBLOCKDESC_3PLANAR_YUV = 1 << 14,   /* 3 planes of separate
  100.                                                     Y, U, V, e.g., YV12. */
  101.  
  102.         SVGA3DBLOCKDESC_RG         = SVGA3DBLOCKDESC_RED |
  103.         SVGA3DBLOCKDESC_GREEN,
  104.         SVGA3DBLOCKDESC_RGB        = SVGA3DBLOCKDESC_RG |
  105.         SVGA3DBLOCKDESC_BLUE,
  106.         SVGA3DBLOCKDESC_RGB_SRGB   = SVGA3DBLOCKDESC_RGB |
  107.         SVGA3DBLOCKDESC_SRGB,
  108.         SVGA3DBLOCKDESC_RGBA       = SVGA3DBLOCKDESC_RGB |
  109.         SVGA3DBLOCKDESC_ALPHA,
  110.         SVGA3DBLOCKDESC_RGBA_SRGB  = SVGA3DBLOCKDESC_RGBA |
  111.         SVGA3DBLOCKDESC_SRGB,
  112.         SVGA3DBLOCKDESC_UV         = SVGA3DBLOCKDESC_U |
  113.         SVGA3DBLOCKDESC_V,
  114.         SVGA3DBLOCKDESC_UVL        = SVGA3DBLOCKDESC_UV |
  115.         SVGA3DBLOCKDESC_LUMINANCE,
  116.         SVGA3DBLOCKDESC_UVW        = SVGA3DBLOCKDESC_UV |
  117.         SVGA3DBLOCKDESC_W,
  118.         SVGA3DBLOCKDESC_UVWA       = SVGA3DBLOCKDESC_UVW |
  119.         SVGA3DBLOCKDESC_ALPHA,
  120.         SVGA3DBLOCKDESC_UVWQ       = SVGA3DBLOCKDESC_U |
  121.         SVGA3DBLOCKDESC_V |
  122.         SVGA3DBLOCKDESC_W |
  123.         SVGA3DBLOCKDESC_Q,
  124.         SVGA3DBLOCKDESC_LA         = SVGA3DBLOCKDESC_LUMINANCE |
  125.         SVGA3DBLOCKDESC_ALPHA,
  126.         SVGA3DBLOCKDESC_R_FP       = SVGA3DBLOCKDESC_RED |
  127.         SVGA3DBLOCKDESC_IEEE_FP,
  128.         SVGA3DBLOCKDESC_RG_FP      = SVGA3DBLOCKDESC_R_FP |
  129.         SVGA3DBLOCKDESC_GREEN,
  130.         SVGA3DBLOCKDESC_RGB_FP     = SVGA3DBLOCKDESC_RG_FP |
  131.         SVGA3DBLOCKDESC_BLUE,
  132.         SVGA3DBLOCKDESC_RGBA_FP    = SVGA3DBLOCKDESC_RGB_FP |
  133.         SVGA3DBLOCKDESC_ALPHA,
  134.         SVGA3DBLOCKDESC_DS         = SVGA3DBLOCKDESC_DEPTH |
  135.         SVGA3DBLOCKDESC_STENCIL,
  136.         SVGA3DBLOCKDESC_YUV        = SVGA3DBLOCKDESC_UV_VIDEO |
  137.         SVGA3DBLOCKDESC_Y,
  138.         SVGA3DBLOCKDESC_AYUV       = SVGA3DBLOCKDESC_ALPHA |
  139.         SVGA3DBLOCKDESC_Y |
  140.         SVGA3DBLOCKDESC_U_VIDEO |
  141.         SVGA3DBLOCKDESC_V_VIDEO,
  142.         SVGA3DBLOCKDESC_RGBE       = SVGA3DBLOCKDESC_RGB |
  143.         SVGA3DBLOCKDESC_EXP,
  144.         SVGA3DBLOCKDESC_COMPRESSED_SRGB = SVGA3DBLOCKDESC_COMPRESSED |
  145.         SVGA3DBLOCKDESC_SRGB,
  146.         SVGA3DBLOCKDESC_NV12       = SVGA3DBLOCKDESC_PLANAR_YUV |
  147.         SVGA3DBLOCKDESC_2PLANAR_YUV,
  148.         SVGA3DBLOCKDESC_YV12       = SVGA3DBLOCKDESC_PLANAR_YUV |
  149.         SVGA3DBLOCKDESC_3PLANAR_YUV,
  150. };
  151.  
  152. /*
  153.  * SVGA3dSurfaceDesc describes the actual pixel data.
  154.  *
  155.  * This structure provides the following information:
  156.  *    1. Block description.
  157.  *    2. Dimensions of a block in the surface.
  158.  *    3. Size of block in bytes.
  159.  *    4. Bit depth of the pixel data.
  160.  *    5. Channel bit depths and masks (if applicable).
  161.  */
  162. #define SVGA3D_CHANNEL_DEF(type)                \
  163.         struct {                                \
  164.                 union {                         \
  165.                         type blue;              \
  166.                         type u;                 \
  167.                         type uv_video;          \
  168.                         type u_video;           \
  169.                 };                              \
  170.                 union {                         \
  171.                         type green;             \
  172.                         type v;                 \
  173.                         type stencil;           \
  174.                         type v_video;           \
  175.                 };                              \
  176.                 union {                         \
  177.                         type red;               \
  178.                         type w;                 \
  179.                         type luminance;         \
  180.                         type y;                 \
  181.                         type depth;             \
  182.                         type data;              \
  183.                 };                              \
  184.                 union {                         \
  185.                         type alpha;             \
  186.                         type q;                 \
  187.                         type exp;               \
  188.                 };                              \
  189.         }
  190.  
  191. struct svga3d_surface_desc {
  192.         enum svga3d_block_desc block_desc;
  193.         SVGA3dSize block_size;
  194.         uint32 bytes_per_block;
  195.         uint32 pitch_bytes_per_block;
  196.  
  197.         struct {
  198.                 uint32 total;
  199.                 SVGA3D_CHANNEL_DEF(uint8);
  200.         } bit_depth;
  201.  
  202.         struct {
  203.                 SVGA3D_CHANNEL_DEF(uint8);
  204.         } bit_offset;
  205. };
  206.  
  207. static const struct svga3d_surface_desc svga3d_surface_descs[] = {
  208.         {SVGA3DBLOCKDESC_NONE,
  209.          {1, 1, 1},  0, 0, {0, {{0}, {0}, {0}, {0} } },
  210.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_FORMAT_INVALID */
  211.  
  212.         {SVGA3DBLOCKDESC_RGB,
  213.          {1, 1, 1},  4, 4, {24, {{8}, {8}, {8}, {0} } },
  214.          {{{0}, {8}, {16}, {24} } } },   /* SVGA3D_X8R8G8B8 */
  215.  
  216.         {SVGA3DBLOCKDESC_RGBA,
  217.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {8} } },
  218.          {{{0}, {8}, {16}, {24} } } },   /* SVGA3D_A8R8G8B8 */
  219.  
  220.         {SVGA3DBLOCKDESC_RGB,
  221.          {1, 1, 1},  2, 2, {16, {{5}, {6}, {5}, {0} } },
  222.          {{{0}, {5}, {11}, {0} } } },    /* SVGA3D_R5G6B5 */
  223.  
  224.         {SVGA3DBLOCKDESC_RGB,
  225.          {1, 1, 1},  2, 2, {15, {{5}, {5}, {5}, {0} } },
  226.          {{{0}, {5}, {10}, {0} } } },    /* SVGA3D_X1R5G5B5 */
  227.  
  228.         {SVGA3DBLOCKDESC_RGBA,
  229.          {1, 1, 1},  2, 2, {16, {{5}, {5}, {5}, {1} } },
  230.          {{{0}, {5}, {10}, {15} } } },   /* SVGA3D_A1R5G5B5 */
  231.  
  232.         {SVGA3DBLOCKDESC_RGBA,
  233.          {1, 1, 1},  2, 2, {16, {{4}, {4}, {4}, {4} } },
  234.          {{{0}, {4}, {8}, {12} } } },    /* SVGA3D_A4R4G4B4 */
  235.  
  236.         {SVGA3DBLOCKDESC_DEPTH,
  237.          {1, 1, 1},  4, 4, {32, {{0}, {0}, {32}, {0} } },
  238.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_Z_D32 */
  239.  
  240.         {SVGA3DBLOCKDESC_DEPTH,
  241.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {16}, {0} } },
  242.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_Z_D16 */
  243.  
  244.         {SVGA3DBLOCKDESC_DS,
  245.          {1, 1, 1},  4, 4, {32, {{0}, {8}, {24}, {0} } },
  246.          {{{0}, {24}, {0}, {0} } } },    /* SVGA3D_Z_D24S8 */
  247.  
  248.         {SVGA3DBLOCKDESC_DS,
  249.          {1, 1, 1},  2, 2, {16, {{0}, {1}, {15}, {0} } },
  250.          {{{0}, {15}, {0}, {0} } } },    /* SVGA3D_Z_D15S1 */
  251.  
  252.         {SVGA3DBLOCKDESC_LUMINANCE,
  253.          {1, 1, 1},  1, 1, {8, {{0}, {0}, {8}, {0} } },
  254.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_LUMINANCE8 */
  255.  
  256.         {SVGA3DBLOCKDESC_LA,
  257.          {1, 1, 1},  1, 1, {8, {{0}, {0}, {4}, {4} } },
  258.          {{{0}, {0}, {0}, {4} } } },     /* SVGA3D_LUMINANCE4_ALPHA4 */
  259.  
  260.         {SVGA3DBLOCKDESC_LUMINANCE,
  261.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {16}, {0} } },
  262.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_LUMINANCE16 */
  263.  
  264.         {SVGA3DBLOCKDESC_LA,
  265.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {8}, {8} } },
  266.          {{{0}, {0}, {0}, {8} } } },     /* SVGA3D_LUMINANCE8_ALPHA8 */
  267.  
  268.         {SVGA3DBLOCKDESC_COMPRESSED,
  269.          {4, 4, 1},  8, 8, {64, {{0}, {0}, {64}, {0} } },
  270.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_DXT1 */
  271.  
  272.         {SVGA3DBLOCKDESC_COMPRESSED,
  273.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  274.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_DXT2 */
  275.  
  276.         {SVGA3DBLOCKDESC_COMPRESSED,
  277.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  278.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_DXT3 */
  279.  
  280.         {SVGA3DBLOCKDESC_COMPRESSED,
  281.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  282.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_DXT4 */
  283.  
  284.         {SVGA3DBLOCKDESC_COMPRESSED,
  285.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  286.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_DXT5 */
  287.  
  288.         {SVGA3DBLOCKDESC_UV,
  289.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {8}, {8} } },
  290.          {{{0}, {0}, {0}, {8} } } },     /* SVGA3D_BUMPU8V8 */
  291.  
  292.         {SVGA3DBLOCKDESC_UVL,
  293.          {1, 1, 1},  2, 2, {16, {{5}, {5}, {6}, {0} } },
  294.          {{{11}, {6}, {0}, {0} } } },    /* SVGA3D_BUMPL6V5U5 */
  295.  
  296.         {SVGA3DBLOCKDESC_UVL,
  297.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {0} } },
  298.          {{{16}, {8}, {0}, {0} } } },    /* SVGA3D_BUMPX8L8V8U8 */
  299.  
  300.         {SVGA3DBLOCKDESC_UVL,
  301.          {1, 1, 1},  3, 3, {24, {{8}, {8}, {8}, {0} } },
  302.          {{{16}, {8}, {0}, {0} } } },    /* SVGA3D_BUMPL8V8U8 */
  303.  
  304.         {SVGA3DBLOCKDESC_RGBA_FP,
  305.          {1, 1, 1},  8, 8, {64, {{16}, {16}, {16}, {16} } },
  306.          {{{32}, {16}, {0}, {48} } } },  /* SVGA3D_ARGB_S10E5 */
  307.  
  308.         {SVGA3DBLOCKDESC_RGBA_FP,
  309.          {1, 1, 1},  16, 16, {128, {{32}, {32}, {32}, {32} } },
  310.          {{{64}, {32}, {0}, {96} } } },  /* SVGA3D_ARGB_S23E8 */
  311.  
  312.         {SVGA3DBLOCKDESC_RGBA,
  313.          {1, 1, 1},  4, 4, {32, {{10}, {10}, {10}, {2} } },
  314.          {{{0}, {10}, {20}, {30} } } },  /* SVGA3D_A2R10G10B10 */
  315.  
  316.         {SVGA3DBLOCKDESC_UV,
  317.          {1, 1, 1},  2, 2, {16, {{8}, {8}, {0}, {0} } },
  318.          {{{8}, {0}, {0}, {0} } } },     /* SVGA3D_V8U8 */
  319.  
  320.         {SVGA3DBLOCKDESC_UVWQ,
  321.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {8} } },
  322.          {{{24}, {16}, {8}, {0} } } },   /* SVGA3D_Q8W8V8U8 */
  323.  
  324.         {SVGA3DBLOCKDESC_UV,
  325.          {1, 1, 1},  2, 2, {16, {{8}, {8}, {0}, {0} } },
  326.          {{{8}, {0}, {0}, {0} } } },     /* SVGA3D_CxV8U8 */
  327.  
  328.         {SVGA3DBLOCKDESC_UVL,
  329.          {1, 1, 1},  4, 4, {24, {{8}, {8}, {8}, {0} } },
  330.          {{{16}, {8}, {0}, {0} } } },    /* SVGA3D_X8L8V8U8 */
  331.  
  332.         {SVGA3DBLOCKDESC_UVWA,
  333.          {1, 1, 1},  4, 4, {32, {{10}, {10}, {10}, {2} } },
  334.          {{{0}, {10}, {20}, {30} } } },  /* SVGA3D_A2W10V10U10 */
  335.  
  336.         {SVGA3DBLOCKDESC_ALPHA,
  337.          {1, 1, 1},  1, 1, {8, {{0}, {0}, {0}, {8} } },
  338.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_ALPHA8 */
  339.  
  340.         {SVGA3DBLOCKDESC_R_FP,
  341.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {16}, {0} } },
  342.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R_S10E5 */
  343.  
  344.         {SVGA3DBLOCKDESC_R_FP,
  345.          {1, 1, 1},  4, 4, {32, {{0}, {0}, {32}, {0} } },
  346.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R_S23E8 */
  347.  
  348.         {SVGA3DBLOCKDESC_RG_FP,
  349.          {1, 1, 1},  4, 4, {32, {{0}, {16}, {16}, {0} } },
  350.          {{{0}, {16}, {0}, {0} } } },    /* SVGA3D_RG_S10E5 */
  351.  
  352.         {SVGA3DBLOCKDESC_RG_FP,
  353.          {1, 1, 1},  8, 8, {64, {{0}, {32}, {32}, {0} } },
  354.          {{{0}, {32}, {0}, {0} } } },    /* SVGA3D_RG_S23E8 */
  355.  
  356.         {SVGA3DBLOCKDESC_BUFFER,
  357.          {1, 1, 1},  1, 1, {8, {{0}, {0}, {8}, {0} } },
  358.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BUFFER */
  359.  
  360.         {SVGA3DBLOCKDESC_DEPTH,
  361.          {1, 1, 1},  4, 4, {32, {{0}, {0}, {24}, {0} } },
  362.          {{{0}, {24}, {0}, {0} } } },    /* SVGA3D_Z_D24X8 */
  363.  
  364.         {SVGA3DBLOCKDESC_UV,
  365.          {1, 1, 1},  4, 4, {32, {{16}, {16}, {0}, {0} } },
  366.          {{{16}, {0}, {0}, {0} } } },    /* SVGA3D_V16U16 */
  367.  
  368.         {SVGA3DBLOCKDESC_RG,
  369.          {1, 1, 1},  4, 4, {32, {{0}, {16}, {16}, {0} } },
  370.          {{{0}, {0}, {16}, {0} } } },    /* SVGA3D_G16R16 */
  371.  
  372.         {SVGA3DBLOCKDESC_RGBA,
  373.          {1, 1, 1},  8, 8, {64, {{16}, {16}, {16}, {16} } },
  374.          {{{32}, {16}, {0}, {48} } } },  /* SVGA3D_A16B16G16R16 */
  375.  
  376.         {SVGA3DBLOCKDESC_YUV,
  377.          {1, 1, 1},  2, 2, {16, {{8}, {0}, {8}, {0} } },
  378.          {{{0}, {0}, {8}, {0} } } },     /* SVGA3D_UYVY */
  379.  
  380.         {SVGA3DBLOCKDESC_YUV,
  381.          {1, 1, 1},  2, 2, {16, {{8}, {0}, {8}, {0} } },
  382.          {{{8}, {0}, {0}, {0} } } },     /* SVGA3D_YUY2 */
  383.  
  384.         {SVGA3DBLOCKDESC_NV12,
  385.          {2, 2, 1},  6, 2, {48, {{0}, {0}, {48}, {0} } },
  386.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_NV12 */
  387.  
  388.         {SVGA3DBLOCKDESC_AYUV,
  389.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {8} } },
  390.          {{{0}, {8}, {16}, {24} } } },   /* SVGA3D_AYUV */
  391.  
  392.         {SVGA3DBLOCKDESC_RGBA,
  393.          {1, 1, 1},  16, 16, {128, {{32}, {32}, {32}, {32} } },
  394.          {{{64}, {32}, {0}, {96} } } },  /* SVGA3D_R32G32B32A32_TYPELESS */
  395.  
  396.         {SVGA3DBLOCKDESC_RGBA,
  397.          {1, 1, 1},  16, 16, {128, {{32}, {32}, {32}, {32} } },
  398.          {{{64}, {32}, {0}, {96} } } },  /* SVGA3D_R32G32B32A32_UINT */
  399.  
  400.         {SVGA3DBLOCKDESC_UVWQ,
  401.          {1, 1, 1},  16, 16, {128, {{32}, {32}, {32}, {32} } },
  402.          {{{64}, {32}, {0}, {96} } } },  /* SVGA3D_R32G32B32A32_SINT */
  403.  
  404.         {SVGA3DBLOCKDESC_RGB,
  405.          {1, 1, 1},  12, 12, {96, {{32}, {32}, {32}, {0} } },
  406.          {{{64}, {32}, {0}, {0} } } },   /* SVGA3D_R32G32B32_TYPELESS */
  407.  
  408.         {SVGA3DBLOCKDESC_RGB_FP,
  409.          {1, 1, 1},  12, 12, {96, {{32}, {32}, {32}, {0} } },
  410.          {{{64}, {32}, {0}, {0} } } },   /* SVGA3D_R32G32B32_FLOAT */
  411.  
  412.         {SVGA3DBLOCKDESC_RGB,
  413.          {1, 1, 1},  12, 12, {96, {{32}, {32}, {32}, {0} } },
  414.          {{{64}, {32}, {0}, {0} } } },   /* SVGA3D_R32G32B32_UINT */
  415.  
  416.         {SVGA3DBLOCKDESC_UVW,
  417.          {1, 1, 1},  12, 12, {96, {{32}, {32}, {32}, {0} } },
  418.          {{{64}, {32}, {0}, {0} } } },   /* SVGA3D_R32G32B32_SINT */
  419.  
  420.         {SVGA3DBLOCKDESC_RGBA,
  421.          {1, 1, 1},  8, 8, {64, {{16}, {16}, {16}, {16} } },
  422.          {{{32}, {16}, {0}, {48} } } },  /* SVGA3D_R16G16B16A16_TYPELESS */
  423.  
  424.         {SVGA3DBLOCKDESC_RGBA,
  425.          {1, 1, 1},  8, 8, {64, {{16}, {16}, {16}, {16} } },
  426.          {{{32}, {16}, {0}, {48} } } },  /* SVGA3D_R16G16B16A16_UINT */
  427.  
  428.         {SVGA3DBLOCKDESC_UVWQ,
  429.          {1, 1, 1},  8, 8, {64, {{16}, {16}, {16}, {16} } },
  430.          {{{32}, {16}, {0}, {48} } } },  /* SVGA3D_R16G16B16A16_SNORM */
  431.  
  432.         {SVGA3DBLOCKDESC_UVWQ,
  433.          {1, 1, 1},  8, 8, {64, {{16}, {16}, {16}, {16} } },
  434.          {{{32}, {16}, {0}, {48} } } },  /* SVGA3D_R16G16B16A16_SINT */
  435.  
  436.         {SVGA3DBLOCKDESC_RG,
  437.          {1, 1, 1},  8, 8, {64, {{0}, {32}, {32}, {0} } },
  438.          {{{0}, {32}, {0}, {0} } } },    /* SVGA3D_R32G32_TYPELESS */
  439.  
  440.         {SVGA3DBLOCKDESC_RG,
  441.          {1, 1, 1},  8, 8, {64, {{0}, {32}, {32}, {0} } },
  442.          {{{0}, {32}, {0}, {0} } } },    /* SVGA3D_R32G32_UINT */
  443.  
  444.         {SVGA3DBLOCKDESC_UV,
  445.          {1, 1, 1},  8, 8, {64, {{0}, {32}, {32}, {0} } },
  446.          {{{0}, {32}, {0}, {0} } } },    /* SVGA3D_R32G32_SINT */
  447.  
  448.         {SVGA3DBLOCKDESC_RG,
  449.          {1, 1, 1},  8, 8, {64, {{0}, {8}, {32}, {0} } },
  450.          {{{0}, {32}, {0}, {0} } } },    /* SVGA3D_R32G8X24_TYPELESS */
  451.  
  452.         {SVGA3DBLOCKDESC_DS,
  453.          {1, 1, 1},  8, 8, {64, {{0}, {8}, {32}, {0} } },
  454.          {{{0}, {32}, {0}, {0} } } },    /* SVGA3D_D32_FLOAT_S8X24_UINT */
  455.  
  456.         {SVGA3DBLOCKDESC_R_FP,
  457.          {1, 1, 1},  8, 8, {64, {{0}, {0}, {32}, {0} } },
  458.          {{{0}, {0}, {0}, {0} } } },    /* SVGA3D_R32_FLOAT_X8_X24_TYPELESS */
  459.  
  460.         {SVGA3DBLOCKDESC_GREEN,
  461.          {1, 1, 1},  8, 8, {64, {{0}, {8}, {0}, {0} } },
  462.          {{{0}, {32}, {0}, {0} } } },    /* SVGA3D_X32_TYPELESS_G8X24_UINT */
  463.  
  464.         {SVGA3DBLOCKDESC_RGBA,
  465.          {1, 1, 1},  4, 4, {32, {{10}, {10}, {10}, {2} } },
  466.          {{{0}, {10}, {20}, {30} } } },  /* SVGA3D_R10G10B10A2_TYPELESS */
  467.  
  468.         {SVGA3DBLOCKDESC_RGBA,
  469.          {1, 1, 1},  4, 4, {32, {{10}, {10}, {10}, {2} } },
  470.          {{{0}, {10}, {20}, {30} } } },  /* SVGA3D_R10G10B10A2_UINT */
  471.  
  472.         {SVGA3DBLOCKDESC_RGB_FP,
  473.          {1, 1, 1},  4, 4, {32, {{10}, {11}, {11}, {0} } },
  474.          {{{0}, {10}, {21}, {0} } } },  /* SVGA3D_R11G11B10_FLOAT */
  475.  
  476.         {SVGA3DBLOCKDESC_RGBA,
  477.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {8} } },
  478.          {{{16}, {8}, {0}, {24} } } },   /* SVGA3D_R8G8B8A8_TYPELESS */
  479.  
  480.         {SVGA3DBLOCKDESC_RGBA,
  481.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {8} } },
  482.          {{{16}, {8}, {0}, {24} } } },   /* SVGA3D_R8G8B8A8_UNORM */
  483.  
  484.         {SVGA3DBLOCKDESC_RGBA_SRGB,
  485.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {8} } },
  486.          {{{16}, {8}, {0}, {24} } } },   /* SVGA3D_R8G8B8A8_UNORM_SRGB */
  487.  
  488.         {SVGA3DBLOCKDESC_RGBA,
  489.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {8} } },
  490.          {{{16}, {8}, {0}, {24} } } },   /* SVGA3D_R8G8B8A8_UINT */
  491.  
  492.         {SVGA3DBLOCKDESC_RGBA,
  493.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {8} } },
  494.          {{{16}, {8}, {0}, {24} } } },   /* SVGA3D_R8G8B8A8_SINT */
  495.  
  496.         {SVGA3DBLOCKDESC_RG,
  497.          {1, 1, 1},  4, 4, {32, {{0}, {16}, {16}, {0} } },
  498.          {{{0}, {16}, {0}, {0} } } },    /* SVGA3D_R16G16_TYPELESS */
  499.  
  500.         {SVGA3DBLOCKDESC_RG_FP,
  501.          {1, 1, 1},  4, 4, {32, {{0}, {16}, {16}, {0} } },
  502.          {{{0}, {16}, {0}, {0} } } },    /* SVGA3D_R16G16_UINT */
  503.  
  504.         {SVGA3DBLOCKDESC_UV,
  505.          {1, 1, 1},  4, 4, {32, {{0}, {16}, {16}, {0} } },
  506.          {{{0}, {16}, {0}, {0} } } },    /* SVGA3D_R16G16_SINT */
  507.  
  508.         {SVGA3DBLOCKDESC_RED,
  509.          {1, 1, 1},  4, 4, {32, {{0}, {0}, {32}, {0} } },
  510.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R32_TYPELESS */
  511.  
  512.         {SVGA3DBLOCKDESC_DEPTH,
  513.          {1, 1, 1},  4, 4, {32, {{0}, {0}, {32}, {0} } },
  514.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_D32_FLOAT */
  515.  
  516.         {SVGA3DBLOCKDESC_RED,
  517.          {1, 1, 1},  4, 4, {32, {{0}, {0}, {32}, {0} } },
  518.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R32_UINT */
  519.  
  520.         {SVGA3DBLOCKDESC_RED,
  521.          {1, 1, 1},  4, 4, {32, {{0}, {0}, {32}, {0} } },
  522.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R32_SINT */
  523.  
  524.         {SVGA3DBLOCKDESC_RG,
  525.          {1, 1, 1},  4, 4, {32, {{0}, {8}, {24}, {0} } },
  526.          {{{0}, {24}, {0}, {0} } } },    /* SVGA3D_R24G8_TYPELESS */
  527.  
  528.         {SVGA3DBLOCKDESC_DS,
  529.          {1, 1, 1},  4, 4, {32, {{0}, {8}, {24}, {0} } },
  530.          {{{0}, {24}, {0}, {0} } } },    /* SVGA3D_D24_UNORM_S8_UINT */
  531.  
  532.         {SVGA3DBLOCKDESC_RED,
  533.          {1, 1, 1},  4, 4, {32, {{0}, {0}, {24}, {0} } },
  534.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R24_UNORM_X8_TYPELESS */
  535.  
  536.         {SVGA3DBLOCKDESC_GREEN,
  537.          {1, 1, 1},  4, 4, {32, {{0}, {8}, {0}, {0} } },
  538.          {{{0}, {24}, {0}, {0} } } },    /* SVGA3D_X24_TYPELESS_G8_UINT */
  539.  
  540.         {SVGA3DBLOCKDESC_RG,
  541.          {1, 1, 1},  2, 2, {16, {{0}, {8}, {8}, {0} } },
  542.          {{{0}, {8}, {0}, {0} } } },     /* SVGA3D_R8G8_TYPELESS */
  543.  
  544.         {SVGA3DBLOCKDESC_RG,
  545.          {1, 1, 1},  2, 2, {16, {{0}, {8}, {8}, {0} } },
  546.          {{{0}, {8}, {0}, {0} } } },     /* SVGA3D_R8G8_UNORM */
  547.  
  548.         {SVGA3DBLOCKDESC_RG,
  549.          {1, 1, 1},  2, 2, {16, {{0}, {8}, {8}, {0} } },
  550.          {{{0}, {8}, {0}, {0} } } },     /* SVGA3D_R8G8_UINT */
  551.  
  552.         {SVGA3DBLOCKDESC_UV,
  553.          {1, 1, 1},  2, 2, {16, {{0}, {8}, {8}, {0} } },
  554.          {{{0}, {8}, {0}, {0} } } },     /* SVGA3D_R8G8_SINT */
  555.  
  556.         {SVGA3DBLOCKDESC_RED,
  557.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {16}, {0} } },
  558.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R16_TYPELESS */
  559.  
  560.         {SVGA3DBLOCKDESC_RED,
  561.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {16}, {0} } },
  562.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R16_UNORM */
  563.  
  564.         {SVGA3DBLOCKDESC_RED,
  565.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {16}, {0} } },
  566.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R16_UINT */
  567.  
  568.         {SVGA3DBLOCKDESC_U,
  569.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {16}, {0} } },
  570.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R16_SNORM */
  571.  
  572.         {SVGA3DBLOCKDESC_U,
  573.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {16}, {0} } },
  574.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R16_SINT */
  575.  
  576.         {SVGA3DBLOCKDESC_RED,
  577.          {1, 1, 1},  1, 1, {8, {{0}, {0}, {8}, {0} } },
  578.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R8_TYPELESS */
  579.  
  580.         {SVGA3DBLOCKDESC_RED,
  581.          {1, 1, 1},  1, 1, {8, {{0}, {0}, {8}, {0} } },
  582.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R8_UNORM */
  583.  
  584.         {SVGA3DBLOCKDESC_RED,
  585.          {1, 1, 1},  1, 1, {8, {{0}, {0}, {8}, {0} } },
  586.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R8_UINT */
  587.  
  588.         {SVGA3DBLOCKDESC_U,
  589.          {1, 1, 1},  1, 1, {8, {{0}, {0}, {8}, {0} } },
  590.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R8_SNORM */
  591.  
  592.         {SVGA3DBLOCKDESC_U,
  593.          {1, 1, 1},  1, 1, {8, {{0}, {0}, {8}, {0} } },
  594.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R8_SINT */
  595.  
  596.         {SVGA3DBLOCKDESC_RED,
  597.          {8, 1, 1},  1, 1, {8, {{0}, {0}, {8}, {0} } },
  598.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_R1_UNORM */
  599.  
  600.         {SVGA3DBLOCKDESC_RGBE,
  601.          {1, 1, 1},  4, 4, {32, {{9}, {9}, {9}, {5} } },
  602.          {{{18}, {9}, {0}, {27} } } },   /* SVGA3D_R9G9B9E5_SHAREDEXP */
  603.  
  604.         {SVGA3DBLOCKDESC_RG,
  605.          {1, 1, 1},  2, 2, {16, {{0}, {8}, {8}, {0} } },
  606.          {{{0}, {8}, {0}, {0} } } },     /* SVGA3D_R8G8_B8G8_UNORM */
  607.  
  608.         {SVGA3DBLOCKDESC_RG,
  609.          {1, 1, 1},  2, 2, {16, {{0}, {8}, {8}, {0} } },
  610.          {{{0}, {8}, {0}, {0} } } },     /* SVGA3D_G8R8_G8B8_UNORM */
  611.  
  612.         {SVGA3DBLOCKDESC_COMPRESSED,
  613.          {4, 4, 1},  8, 8, {64, {{0}, {0}, {64}, {0} } },
  614.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC1_TYPELESS */
  615.  
  616.         {SVGA3DBLOCKDESC_COMPRESSED_SRGB,
  617.          {4, 4, 1},  8, 8, {64, {{0}, {0}, {64}, {0} } },
  618.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC1_UNORM_SRGB */
  619.  
  620.         {SVGA3DBLOCKDESC_COMPRESSED,
  621.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  622.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC2_TYPELESS */
  623.  
  624.         {SVGA3DBLOCKDESC_COMPRESSED_SRGB,
  625.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  626.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC2_UNORM_SRGB */
  627.  
  628.         {SVGA3DBLOCKDESC_COMPRESSED,
  629.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  630.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC3_TYPELESS */
  631.  
  632.         {SVGA3DBLOCKDESC_COMPRESSED_SRGB,
  633.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  634.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC3_UNORM_SRGB */
  635.  
  636.         {SVGA3DBLOCKDESC_COMPRESSED,
  637.          {4, 4, 1},  8, 8, {64, {{0}, {0}, {64}, {0} } },
  638.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC4_TYPELESS */
  639.  
  640.         {SVGA3DBLOCKDESC_COMPRESSED,
  641.          {4, 4, 1},  8, 8, {64, {{0}, {0}, {64}, {0} } },
  642.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC4_UNORM */
  643.  
  644.         {SVGA3DBLOCKDESC_COMPRESSED,
  645.          {4, 4, 1},  8, 8, {64, {{0}, {0}, {64}, {0} } },
  646.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC4_SNORM */
  647.  
  648.         {SVGA3DBLOCKDESC_COMPRESSED,
  649.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  650.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC5_TYPELESS */
  651.  
  652.         {SVGA3DBLOCKDESC_COMPRESSED,
  653.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  654.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC5_UNORM */
  655.  
  656.         {SVGA3DBLOCKDESC_COMPRESSED,
  657.          {4, 4, 1},  16, 16, {128, {{0}, {0}, {128}, {0} } },
  658.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_BC5_SNORM */
  659.  
  660.         {SVGA3DBLOCKDESC_RGBA,
  661.          {1, 1, 1},  4, 4, {32, {{10}, {10}, {10}, {2} } },
  662.          {{{0}, {10}, {20}, {30} } } },  /* SVGA3D_R10G10B10_XR_BIAS_A2_UNORM */
  663.  
  664.         {SVGA3DBLOCKDESC_RGBA,
  665.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {8} } },
  666.          {{{0}, {8}, {16}, {24} } } },   /* SVGA3D_B8G8R8A8_TYPELESS */
  667.  
  668.         {SVGA3DBLOCKDESC_RGBA_SRGB,
  669.          {1, 1, 1},  4, 4, {32, {{8}, {8}, {8}, {8} } },
  670.          {{{0}, {8}, {16}, {24} } } },   /* SVGA3D_B8G8R8A8_UNORM_SRGB */
  671.  
  672.         {SVGA3DBLOCKDESC_RGB,
  673.          {1, 1, 1},  4, 4, {24, {{8}, {8}, {8}, {0} } },
  674.          {{{0}, {8}, {16}, {24} } } },   /* SVGA3D_B8G8R8X8_TYPELESS */
  675.  
  676.         {SVGA3DBLOCKDESC_RGB_SRGB,
  677.          {1, 1, 1},  4, 4, {24, {{8}, {8}, {8}, {0} } },
  678.          {{{0}, {8}, {16}, {24} } } },   /* SVGA3D_B8G8R8X8_UNORM_SRGB */
  679.  
  680.         {SVGA3DBLOCKDESC_DEPTH,
  681.          {1, 1, 1},  2, 2, {16, {{0}, {0}, {16}, {0} } },
  682.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_Z_DF16 */
  683.  
  684.         {SVGA3DBLOCKDESC_DS,
  685.          {1, 1, 1},  4, 4, {32, {{0}, {8}, {24}, {0} } },
  686.          {{{0}, {24}, {0}, {0} } } },    /* SVGA3D_Z_DF24 */
  687.  
  688.         {SVGA3DBLOCKDESC_DS,
  689.          {1, 1, 1},  4, 4, {32, {{0}, {8}, {24}, {0} } },
  690.          {{{0}, {24}, {0}, {0} } } },    /* SVGA3D_Z_D24S8_INT */
  691.  
  692.         {SVGA3DBLOCKDESC_YV12,
  693.          {2, 2, 1},  6, 2, {48, {{0}, {0}, {48}, {0} } },
  694.          {{{0}, {0}, {0}, {0} } } },     /* SVGA3D_YV12 */
  695. };
  696.  
  697.  
  698. extern const struct svga3d_surface_desc g_SVGA3dSurfaceDescs[];
  699. extern int g_SVGA3dSurfaceDescs_size;
  700.  
  701. static inline uint32 clamped_umul32(uint32 a, uint32 b)
  702. {
  703.         uint64_t tmp = (uint64_t) a*b;
  704.         return (tmp > (uint64_t) ((uint32) -1)) ? (uint32) -1 : tmp;
  705. }
  706.  
  707. static inline const struct svga3d_surface_desc *
  708. svga3dsurface_get_desc(SVGA3dSurfaceFormat format)
  709. {
  710.         if (format < ARRAY_SIZE(svga3d_surface_descs))
  711.                 return &svga3d_surface_descs[format];
  712.  
  713.         return &svga3d_surface_descs[SVGA3D_FORMAT_INVALID];
  714. }
  715.  
  716. /*
  717.  *----------------------------------------------------------------------
  718.  *
  719.  * svga3dsurface_get_mip_size --
  720.  *
  721.  *      Given a base level size and the mip level, compute the size of
  722.  *      the mip level.
  723.  *
  724.  * Results:
  725.  *      See above.
  726.  *
  727.  * Side effects:
  728.  *      None.
  729.  *
  730.  *----------------------------------------------------------------------
  731.  */
  732.  
  733. static inline SVGA3dSize
  734. svga3dsurface_get_mip_size(SVGA3dSize base_level, uint32 mip_level)
  735. {
  736.         SVGA3dSize size;
  737.  
  738.         size.width = max_t(uint32, base_level.width >> mip_level, 1);
  739.         size.height = max_t(uint32, base_level.height >> mip_level, 1);
  740.         size.depth = max_t(uint32, base_level.depth >> mip_level, 1);
  741.         return size;
  742. }
  743.  
  744. static inline void
  745. svga3dsurface_get_size_in_blocks(const struct svga3d_surface_desc *desc,
  746.                                  const SVGA3dSize *pixel_size,
  747.                                  SVGA3dSize *block_size)
  748. {
  749.         block_size->width = DIV_ROUND_UP(pixel_size->width,
  750.                                          desc->block_size.width);
  751.         block_size->height = DIV_ROUND_UP(pixel_size->height,
  752.                                           desc->block_size.height);
  753.         block_size->depth = DIV_ROUND_UP(pixel_size->depth,
  754.                                          desc->block_size.depth);
  755. }
  756.  
  757. static inline bool
  758. svga3dsurface_is_planar_surface(const struct svga3d_surface_desc *desc)
  759. {
  760.         return (desc->block_desc & SVGA3DBLOCKDESC_PLANAR_YUV) != 0;
  761. }
  762.  
  763. static inline uint32
  764. svga3dsurface_calculate_pitch(const struct svga3d_surface_desc *desc,
  765.                               const SVGA3dSize *size)
  766. {
  767.         uint32 pitch;
  768.         SVGA3dSize blocks;
  769.  
  770.         svga3dsurface_get_size_in_blocks(desc, size, &blocks);
  771.  
  772.         pitch = blocks.width * desc->pitch_bytes_per_block;
  773.  
  774.         return pitch;
  775. }
  776.  
  777. /*
  778.  *-----------------------------------------------------------------------------
  779.  *
  780.  * svga3dsurface_get_image_buffer_size --
  781.  *
  782.  *      Return the number of bytes of buffer space required to store
  783.  *      one image of a surface, optionally using the specified pitch.
  784.  *
  785.  *      If pitch is zero, it is assumed that rows are tightly packed.
  786.  *
  787.  *      This function is overflow-safe. If the result would have
  788.  *      overflowed, instead we return MAX_UINT32.
  789.  *
  790.  * Results:
  791.  *      Byte count.
  792.  *
  793.  * Side effects:
  794.  *      None.
  795.  *
  796.  *-----------------------------------------------------------------------------
  797.  */
  798.  
  799. static inline uint32
  800. svga3dsurface_get_image_buffer_size(const struct svga3d_surface_desc *desc,
  801.                                     const SVGA3dSize *size,
  802.                                     uint32 pitch)
  803. {
  804.         SVGA3dSize image_blocks;
  805.         uint32 slice_size, total_size;
  806.  
  807.         svga3dsurface_get_size_in_blocks(desc, size, &image_blocks);
  808.  
  809.         if (svga3dsurface_is_planar_surface(desc)) {
  810.                 total_size = clamped_umul32(image_blocks.width,
  811.                                             image_blocks.height);
  812.                 total_size = clamped_umul32(total_size, image_blocks.depth);
  813.                 total_size = clamped_umul32(total_size, desc->bytes_per_block);
  814.                 return total_size;
  815.         }
  816.  
  817.         if (pitch == 0)
  818.                 pitch = svga3dsurface_calculate_pitch(desc, size);
  819.  
  820.         slice_size = clamped_umul32(image_blocks.height, pitch);
  821.         total_size = clamped_umul32(slice_size, image_blocks.depth);
  822.  
  823.         return total_size;
  824. }
  825.  
  826.  
  827. static inline uint32
  828. svga3dsurface_get_image_offset(SVGA3dSurfaceFormat format,
  829.                                SVGA3dSize baseLevelSize,
  830.                                uint32 numMipLevels,
  831.                                uint32 face,
  832.                                uint32 mip)
  833.  
  834. {
  835.    uint32 offset;
  836.    uint32 mipChainBytes;
  837.    uint32 mipChainBytesToLevel;
  838.    uint32 i;
  839.    const struct svga3d_surface_desc *desc;
  840.    SVGA3dSize mipSize;
  841.    uint32 bytes;
  842.  
  843.    desc = svga3dsurface_get_desc(format);
  844.  
  845.    mipChainBytes = 0;
  846.    mipChainBytesToLevel = 0;
  847.    for (i = 0; i < numMipLevels; i++) {
  848.       mipSize = svga3dsurface_get_mip_size(baseLevelSize, i);
  849.       bytes = svga3dsurface_get_image_buffer_size(desc, &mipSize, 0);
  850.       mipChainBytes += bytes;
  851.       if (i < mip) {
  852.          mipChainBytesToLevel += bytes;
  853.       }
  854.    }
  855.  
  856.    offset = mipChainBytes * face + mipChainBytesToLevel;
  857.  
  858.    return offset;
  859. }
  860.  
  861.  
  862. static inline uint32
  863. svga3dsurface_get_serialized_size(SVGA3dSurfaceFormat format,
  864.                                   SVGA3dSize base_level_size,
  865.                                   uint32 num_mip_levels,
  866.                                   bool cubemap)
  867. {
  868.         const struct svga3d_surface_desc *desc = svga3dsurface_get_desc(format);
  869.         uint64_t total_size = 0;
  870.         uint32 mip;
  871.  
  872.         for (mip = 0; mip < num_mip_levels; mip++) {
  873.                 SVGA3dSize size =
  874.                         svga3dsurface_get_mip_size(base_level_size, mip);
  875.                 total_size += svga3dsurface_get_image_buffer_size(desc,
  876.                                                                   &size, 0);
  877.         }
  878.  
  879.         if (cubemap)
  880.                 total_size *= SVGA3D_MAX_SURFACE_FACES;
  881.  
  882.         return (total_size > (uint64_t) MAX_UINT32) ? MAX_UINT32 :
  883.                                                       (uint32) total_size;
  884. }
  885.  
  886.  
  887. /**
  888.  * Compute the offset (in bytes) to a pixel in an image (or volume).
  889.  * 'width' is the image width in pixels
  890.  * 'height' is the image height in pixels
  891.  */
  892. static inline uint32
  893. svga3dsurface_get_pixel_offset(SVGA3dSurfaceFormat format,
  894.                                uint32 width, uint32 height,
  895.                                uint32 x, uint32 y, uint32 z)
  896. {
  897.    const struct svga3d_surface_desc *desc = svga3dsurface_get_desc(format);
  898.    const uint32 bw = desc->block_size.width, bh = desc->block_size.height;
  899.    const uint32 bd = desc->block_size.depth;
  900.    const uint32 rowstride = DIV_ROUND_UP(width, bw) * desc->bytes_per_block;
  901.    const uint32 imgstride = DIV_ROUND_UP(height, bh) * rowstride;
  902.    const uint32 offset = (z / bd * imgstride +
  903.                           y / bh * rowstride +
  904.                           x / bw * desc->bytes_per_block);
  905.    return offset;
  906. }
  907.