Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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