Subversion Repositories Kolibri OS

Rev

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