Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/vmwgfx: Add and make use of a header for surface size calculation.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Dmitry Torokhov <dtor@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Thomas Hellstrom and committed by
Dave Airlie
7e8d9da3 543831cf

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