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 70enum 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 206struct 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 222static 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 708static 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 714static inline const struct svga3d_surface_desc * 715svga3dsurface_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 740static inline surf_size_struct 741svga3dsurface_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 751static inline void 752svga3dsurface_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 764static inline bool 765svga3dsurface_is_planar_surface(const struct svga3d_surface_desc *desc) 766{ 767 return (desc->block_desc & SVGA3DBLOCKDESC_PLANAR_YUV) != 0; 768} 769 770static inline u32 771svga3dsurface_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 806static inline u32 807svga3dsurface_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 833static inline u32 834svga3dsurface_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 */ 864static inline u32 865svga3dsurface_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 881static inline u32 882svga3dsurface_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