linux/drivers/gpu/drm/vmwgfx/svga3d_surfacedefs.h
<<
>>
Prefs
   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
  67enum 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
 203struct 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
 219static 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
 705static 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
 711static inline const struct svga3d_surface_desc *
 712svga3dsurface_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
 737static inline surf_size_struct
 738svga3dsurface_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
 748static inline void
 749svga3dsurface_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
 761static inline bool
 762svga3dsurface_is_planar_surface(const struct svga3d_surface_desc *desc)
 763{
 764        return (desc->block_desc & SVGA3DBLOCKDESC_PLANAR_YUV) != 0;
 765}
 766
 767static inline u32
 768svga3dsurface_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
 803static inline u32
 804svga3dsurface_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
 830static inline u32
 831svga3dsurface_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 */
 861static inline u32
 862svga3dsurface_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
 878static inline u32
 879svga3dsurface_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