1 /**************************************************************************
2  *
3  * Copyright © 2008-2015 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 struct svga3d_channel_def {
175 	union {
176 		u8 blue;
177 		u8 u;
178 		u8 uv_video;
179 		u8 u_video;
180 	};
181 	union {
182 		u8 green;
183 		u8 v;
184 		u8 stencil;
185 		u8 v_video;
186 	};
187 	union {
188 		u8 red;
189 		u8 w;
190 		u8 luminance;
191 		u8 y;
192 		u8 depth;
193 		u8 data;
194 	};
195 	union {
196 		u8 alpha;
197 		u8 q;
198 		u8 exp;
199 	};
200 };
201 
202 struct svga3d_surface_desc {
203 	SVGA3dSurfaceFormat format;
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 	u32 total_bit_depth;
210 	struct svga3d_channel_def bit_depth;
211 	struct svga3d_channel_def bit_offset;
212 };
213 
214 static const struct svga3d_surface_desc svga3d_surface_descs[] = {
215    {SVGA3D_FORMAT_INVALID, SVGA3DBLOCKDESC_NONE,
216       {1, 1, 1},  0, 0,
217       0, {{0}, {0}, {0}, {0}},
218       {{0}, {0}, {0}, {0}}},
219 
220    {SVGA3D_X8R8G8B8, SVGA3DBLOCKDESC_RGB,
221       {1, 1, 1},  4, 4,
222       24, {{8}, {8}, {8}, {0}},
223       {{0}, {8}, {16}, {24}}},
224 
225    {SVGA3D_A8R8G8B8, SVGA3DBLOCKDESC_RGBA,
226       {1, 1, 1},  4, 4,
227       32, {{8}, {8}, {8}, {8}},
228       {{0}, {8}, {16}, {24}}},
229 
230    {SVGA3D_R5G6B5, SVGA3DBLOCKDESC_RGB,
231       {1, 1, 1},  2, 2,
232       16, {{5}, {6}, {5}, {0}},
233       {{0}, {5}, {11}, {0}}},
234 
235    {SVGA3D_X1R5G5B5, SVGA3DBLOCKDESC_RGB,
236       {1, 1, 1},  2, 2,
237       15, {{5}, {5}, {5}, {0}},
238       {{0}, {5}, {10}, {0}}},
239 
240    {SVGA3D_A1R5G5B5, SVGA3DBLOCKDESC_RGBA,
241       {1, 1, 1},  2, 2,
242       16, {{5}, {5}, {5}, {1}},
243       {{0}, {5}, {10}, {15}}},
244 
245    {SVGA3D_A4R4G4B4, SVGA3DBLOCKDESC_RGBA,
246       {1, 1, 1},  2, 2,
247       16, {{4}, {4}, {4}, {4}},
248       {{0}, {4}, {8}, {12}}},
249 
250    {SVGA3D_Z_D32, SVGA3DBLOCKDESC_DEPTH,
251       {1, 1, 1},  4, 4,
252       32, {{0}, {0}, {32}, {0}},
253       {{0}, {0}, {0}, {0}}},
254 
255    {SVGA3D_Z_D16, SVGA3DBLOCKDESC_DEPTH,
256       {1, 1, 1},  2, 2,
257       16, {{0}, {0}, {16}, {0}},
258       {{0}, {0}, {0}, {0}}},
259 
260    {SVGA3D_Z_D24S8, SVGA3DBLOCKDESC_DS,
261       {1, 1, 1},  4, 4,
262       32, {{0}, {8}, {24}, {0}},
263       {{0}, {24}, {0}, {0}}},
264 
265    {SVGA3D_Z_D15S1, SVGA3DBLOCKDESC_DS,
266       {1, 1, 1},  2, 2,
267       16, {{0}, {1}, {15}, {0}},
268       {{0}, {15}, {0}, {0}}},
269 
270    {SVGA3D_LUMINANCE8, SVGA3DBLOCKDESC_LUMINANCE,
271       {1, 1, 1},  1, 1,
272       8, {{0}, {0}, {8}, {0}},
273       {{0}, {0}, {0}, {0}}},
274 
275    {SVGA3D_LUMINANCE4_ALPHA4, SVGA3DBLOCKDESC_LA,
276     {1  , 1, 1},  1, 1,
277       8, {{0}, {0}, {4}, {4}},
278       {{0}, {0}, {0}, {4}}},
279 
280    {SVGA3D_LUMINANCE16, SVGA3DBLOCKDESC_LUMINANCE,
281       {1, 1, 1},  2, 2,
282       16, {{0}, {0}, {16}, {0}},
283       {{0}, {0}, {0}, {0}}},
284 
285    {SVGA3D_LUMINANCE8_ALPHA8, SVGA3DBLOCKDESC_LA,
286       {1, 1, 1},  2, 2,
287       16, {{0}, {0}, {8}, {8}},
288       {{0}, {0}, {0}, {8}}},
289 
290    {SVGA3D_DXT1, SVGA3DBLOCKDESC_COMPRESSED,
291       {4, 4, 1},  8, 8,
292       64, {{0}, {0}, {64}, {0}},
293       {{0}, {0}, {0}, {0}}},
294 
295    {SVGA3D_DXT2, SVGA3DBLOCKDESC_COMPRESSED,
296       {4, 4, 1},  16, 16,
297       128, {{0}, {0}, {128}, {0}},
298       {{0}, {0}, {0}, {0}}},
299 
300    {SVGA3D_DXT3, SVGA3DBLOCKDESC_COMPRESSED,
301       {4, 4, 1},  16, 16,
302       128, {{0}, {0}, {128}, {0}},
303       {{0}, {0}, {0}, {0}}},
304 
305    {SVGA3D_DXT4, SVGA3DBLOCKDESC_COMPRESSED,
306       {4, 4, 1},  16, 16,
307       128, {{0}, {0}, {128}, {0}},
308       {{0}, {0}, {0}, {0}}},
309 
310    {SVGA3D_DXT5, SVGA3DBLOCKDESC_COMPRESSED,
311       {4, 4, 1},  16, 16,
312       128, {{0}, {0}, {128}, {0}},
313       {{0}, {0}, {0}, {0}}},
314 
315    {SVGA3D_BUMPU8V8, SVGA3DBLOCKDESC_UV,
316       {1, 1, 1},  2, 2,
317       16, {{0}, {0}, {8}, {8}},
318       {{0}, {0}, {0}, {8}}},
319 
320    {SVGA3D_BUMPL6V5U5, SVGA3DBLOCKDESC_UVL,
321       {1, 1, 1},  2, 2,
322       16, {{5}, {5}, {6}, {0}},
323       {{11}, {6}, {0}, {0}}},
324 
325    {SVGA3D_BUMPX8L8V8U8, SVGA3DBLOCKDESC_UVL,
326       {1, 1, 1},  4, 4,
327       32, {{8}, {8}, {8}, {0}},
328       {{16}, {8}, {0}, {0}}},
329 
330    {SVGA3D_BUMPL8V8U8, SVGA3DBLOCKDESC_UVL,
331       {1, 1, 1},  3, 3,
332       24, {{8}, {8}, {8}, {0}},
333       {{16}, {8}, {0}, {0}}},
334 
335    {SVGA3D_ARGB_S10E5, SVGA3DBLOCKDESC_RGBA_FP,
336       {1, 1, 1},  8, 8,
337       64, {{16}, {16}, {16}, {16}},
338       {{32}, {16}, {0}, {48}}},
339 
340    {SVGA3D_ARGB_S23E8, SVGA3DBLOCKDESC_RGBA_FP,
341       {1, 1, 1},  16, 16,
342       128, {{32}, {32}, {32}, {32}},
343       {{64}, {32}, {0}, {96}}},
344 
345    {SVGA3D_A2R10G10B10, SVGA3DBLOCKDESC_RGBA,
346       {1, 1, 1},  4, 4,
347       32, {{10}, {10}, {10}, {2}},
348       {{0}, {10}, {20}, {30}}},
349 
350    {SVGA3D_V8U8, SVGA3DBLOCKDESC_UV,
351       {1, 1, 1},  2, 2,
352       16, {{8}, {8}, {0}, {0}},
353       {{8}, {0}, {0}, {0}}},
354 
355    {SVGA3D_Q8W8V8U8, SVGA3DBLOCKDESC_UVWQ,
356       {1, 1, 1},  4, 4,
357       32, {{8}, {8}, {8}, {8}},
358       {{24}, {16}, {8}, {0}}},
359 
360    {SVGA3D_CxV8U8, SVGA3DBLOCKDESC_UV,
361       {1, 1, 1},  2, 2,
362       16, {{8}, {8}, {0}, {0}},
363       {{8}, {0}, {0}, {0}}},
364 
365    {SVGA3D_X8L8V8U8, SVGA3DBLOCKDESC_UVL,
366       {1, 1, 1},  4, 4,
367       24, {{8}, {8}, {8}, {0}},
368       {{16}, {8}, {0}, {0}}},
369 
370    {SVGA3D_A2W10V10U10, SVGA3DBLOCKDESC_UVWA,
371       {1, 1, 1},  4, 4,
372       32, {{10}, {10}, {10}, {2}},
373       {{0}, {10}, {20}, {30}}},
374 
375    {SVGA3D_ALPHA8, SVGA3DBLOCKDESC_ALPHA,
376       {1, 1, 1},  1, 1,
377       8, {{0}, {0}, {0}, {8}},
378       {{0}, {0}, {0}, {0}}},
379 
380    {SVGA3D_R_S10E5, SVGA3DBLOCKDESC_R_FP,
381       {1, 1, 1},  2, 2,
382       16, {{0}, {0}, {16}, {0}},
383       {{0}, {0}, {0}, {0}}},
384 
385    {SVGA3D_R_S23E8, SVGA3DBLOCKDESC_R_FP,
386       {1, 1, 1},  4, 4,
387       32, {{0}, {0}, {32}, {0}},
388       {{0}, {0}, {0}, {0}}},
389 
390    {SVGA3D_RG_S10E5, SVGA3DBLOCKDESC_RG_FP,
391       {1, 1, 1},  4, 4,
392       32, {{0}, {16}, {16}, {0}},
393       {{0}, {16}, {0}, {0}}},
394 
395    {SVGA3D_RG_S23E8, SVGA3DBLOCKDESC_RG_FP,
396       {1, 1, 1},  8, 8,
397       64, {{0}, {32}, {32}, {0}},
398       {{0}, {32}, {0}, {0}}},
399 
400    {SVGA3D_BUFFER, SVGA3DBLOCKDESC_BUFFER,
401       {1, 1, 1},  1, 1,
402       8, {{0}, {0}, {8}, {0}},
403       {{0}, {0}, {0}, {0}}},
404 
405    {SVGA3D_Z_D24X8, SVGA3DBLOCKDESC_DEPTH,
406       {1, 1, 1},  4, 4,
407       32, {{0}, {0}, {24}, {0}},
408       {{0}, {24}, {0}, {0}}},
409 
410    {SVGA3D_V16U16, SVGA3DBLOCKDESC_UV,
411       {1, 1, 1},  4, 4,
412       32, {{16}, {16}, {0}, {0}},
413       {{16}, {0}, {0}, {0}}},
414 
415    {SVGA3D_G16R16, SVGA3DBLOCKDESC_RG,
416       {1, 1, 1},  4, 4,
417       32, {{0}, {16}, {16}, {0}},
418       {{0}, {0}, {16}, {0}}},
419 
420    {SVGA3D_A16B16G16R16, SVGA3DBLOCKDESC_RGBA,
421       {1, 1, 1},  8, 8,
422       64, {{16}, {16}, {16}, {16}},
423       {{32}, {16}, {0}, {48}}},
424 
425    {SVGA3D_UYVY, SVGA3DBLOCKDESC_YUV,
426       {1, 1, 1},  2, 2,
427       16, {{8}, {0}, {8}, {0}},
428       {{0}, {0}, {8}, {0}}},
429 
430    {SVGA3D_YUY2, SVGA3DBLOCKDESC_YUV,
431       {1, 1, 1},  2, 2,
432       16, {{8}, {0}, {8}, {0}},
433       {{8}, {0}, {0}, {0}}},
434 
435    {SVGA3D_NV12, SVGA3DBLOCKDESC_NV12,
436       {2, 2, 1},  6, 2,
437       48, {{0}, {0}, {48}, {0}},
438       {{0}, {0}, {0}, {0}}},
439 
440    {SVGA3D_AYUV, SVGA3DBLOCKDESC_AYUV,
441       {1, 1, 1},  4, 4,
442       32, {{8}, {8}, {8}, {8}},
443       {{0}, {8}, {16}, {24}}},
444 
445    {SVGA3D_R32G32B32A32_TYPELESS, SVGA3DBLOCKDESC_RGBA,
446       {1, 1, 1},  16, 16,
447       128, {{32}, {32}, {32}, {32}},
448       {{64}, {32}, {0}, {96}}},
449 
450    {SVGA3D_R32G32B32A32_UINT, SVGA3DBLOCKDESC_RGBA,
451       {1, 1, 1},  16, 16,
452       128, {{32}, {32}, {32}, {32}},
453       {{64}, {32}, {0}, {96}}},
454 
455    {SVGA3D_R32G32B32A32_SINT, SVGA3DBLOCKDESC_UVWQ,
456       {1, 1, 1},  16, 16,
457       128, {{32}, {32}, {32}, {32}},
458       {{64}, {32}, {0}, {96}}},
459 
460    {SVGA3D_R32G32B32_TYPELESS, SVGA3DBLOCKDESC_RGB,
461       {1, 1, 1},  12, 12,
462       96, {{32}, {32}, {32}, {0}},
463       {{64}, {32}, {0}, {0}}},
464 
465    {SVGA3D_R32G32B32_FLOAT, SVGA3DBLOCKDESC_RGB_FP,
466       {1, 1, 1},  12, 12,
467       96, {{32}, {32}, {32}, {0}},
468       {{64}, {32}, {0}, {0}}},
469 
470    {SVGA3D_R32G32B32_UINT, SVGA3DBLOCKDESC_RGB,
471       {1, 1, 1},  12, 12,
472       96, {{32}, {32}, {32}, {0}},
473       {{64}, {32}, {0}, {0}}},
474 
475    {SVGA3D_R32G32B32_SINT, SVGA3DBLOCKDESC_UVW,
476       {1, 1, 1},  12, 12,
477       96, {{32}, {32}, {32}, {0}},
478       {{64}, {32}, {0}, {0}}},
479 
480    {SVGA3D_R16G16B16A16_TYPELESS, SVGA3DBLOCKDESC_RGBA,
481       {1, 1, 1},  8, 8,
482       64, {{16}, {16}, {16}, {16}},
483       {{32}, {16}, {0}, {48}}},
484 
485    {SVGA3D_R16G16B16A16_UINT, SVGA3DBLOCKDESC_RGBA,
486       {1, 1, 1},  8, 8,
487       64, {{16}, {16}, {16}, {16}},
488       {{32}, {16}, {0}, {48}}},
489 
490    {SVGA3D_R16G16B16A16_SNORM, SVGA3DBLOCKDESC_UVWQ,
491       {1, 1, 1},  8, 8,
492       64, {{16}, {16}, {16}, {16}},
493       {{32}, {16}, {0}, {48}}},
494 
495    {SVGA3D_R16G16B16A16_SINT, SVGA3DBLOCKDESC_UVWQ,
496       {1, 1, 1},  8, 8,
497       64, {{16}, {16}, {16}, {16}},
498       {{32}, {16}, {0}, {48}}},
499 
500    {SVGA3D_R32G32_TYPELESS, SVGA3DBLOCKDESC_RG,
501       {1, 1, 1},  8, 8,
502       64, {{0}, {32}, {32}, {0}},
503       {{0}, {32}, {0}, {0}}},
504 
505    {SVGA3D_R32G32_UINT, SVGA3DBLOCKDESC_RG,
506       {1, 1, 1},  8, 8,
507       64, {{0}, {32}, {32}, {0}},
508       {{0}, {32}, {0}, {0}}},
509 
510    {SVGA3D_R32G32_SINT, SVGA3DBLOCKDESC_UV,
511       {1, 1, 1},  8, 8,
512       64, {{0}, {32}, {32}, {0}},
513       {{0}, {32}, {0}, {0}}},
514 
515    {SVGA3D_R32G8X24_TYPELESS, SVGA3DBLOCKDESC_RG,
516       {1, 1, 1},  8, 8,
517       64, {{0}, {8}, {32}, {0}},
518       {{0}, {32}, {0}, {0}}},
519 
520    {SVGA3D_D32_FLOAT_S8X24_UINT, SVGA3DBLOCKDESC_DS,
521       {1, 1, 1},  8, 8,
522       64, {{0}, {8}, {32}, {0}},
523       {{0}, {32}, {0}, {0}}},
524 
525    {SVGA3D_R32_FLOAT_X8X24_TYPELESS, SVGA3DBLOCKDESC_R_FP,
526       {1, 1, 1},  8, 8,
527       64, {{0}, {0}, {32}, {0}},
528       {{0}, {0}, {0}, {0}}},
529 
530    {SVGA3D_X32_TYPELESS_G8X24_UINT, SVGA3DBLOCKDESC_GREEN,
531       {1, 1, 1},  8, 8,
532       64, {{0}, {8}, {0}, {0}},
533       {{0}, {32}, {0}, {0}}},
534 
535    {SVGA3D_R10G10B10A2_TYPELESS, SVGA3DBLOCKDESC_RGBA,
536       {1, 1, 1},  4, 4,
537       32, {{10}, {10}, {10}, {2}},
538       {{0}, {10}, {20}, {30}}},
539 
540    {SVGA3D_R10G10B10A2_UINT, SVGA3DBLOCKDESC_RGBA,
541       {1, 1, 1},  4, 4,
542       32, {{10}, {10}, {10}, {2}},
543       {{0}, {10}, {20}, {30}}},
544 
545    {SVGA3D_R11G11B10_FLOAT, SVGA3DBLOCKDESC_RGB_FP,
546       {1, 1, 1},  4, 4,
547       32, {{10}, {11}, {11}, {0}},
548       {{0}, {10}, {21}, {0}}},
549 
550    {SVGA3D_R8G8B8A8_TYPELESS, SVGA3DBLOCKDESC_RGBA,
551       {1, 1, 1},  4, 4,
552       32, {{8}, {8}, {8}, {8}},
553       {{16}, {8}, {0}, {24}}},
554 
555    {SVGA3D_R8G8B8A8_UNORM, SVGA3DBLOCKDESC_RGBA,
556       {1, 1, 1},  4, 4,
557       32, {{8}, {8}, {8}, {8}},
558       {{16}, {8}, {0}, {24}}},
559 
560    {SVGA3D_R8G8B8A8_UNORM_SRGB, SVGA3DBLOCKDESC_RGBA_SRGB,
561       {1, 1, 1},  4, 4,
562       32, {{8}, {8}, {8}, {8}},
563       {{16}, {8}, {0}, {24}}},
564 
565    {SVGA3D_R8G8B8A8_UINT, SVGA3DBLOCKDESC_RGBA,
566       {1, 1, 1},  4, 4,
567       32, {{8}, {8}, {8}, {8}},
568       {{16}, {8}, {0}, {24}}},
569 
570    {SVGA3D_R8G8B8A8_SINT, SVGA3DBLOCKDESC_RGBA,
571       {1, 1, 1},  4, 4,
572       32, {{8}, {8}, {8}, {8}},
573       {{16}, {8}, {0}, {24}}},
574 
575    {SVGA3D_R16G16_TYPELESS, SVGA3DBLOCKDESC_RG,
576       {1, 1, 1},  4, 4,
577       32, {{0}, {16}, {16}, {0}},
578       {{0}, {16}, {0}, {0}}},
579 
580    {SVGA3D_R16G16_UINT, SVGA3DBLOCKDESC_RG_FP,
581       {1, 1, 1},  4, 4,
582       32, {{0}, {16}, {16}, {0}},
583       {{0}, {16}, {0}, {0}}},
584 
585    {SVGA3D_R16G16_SINT, SVGA3DBLOCKDESC_UV,
586       {1, 1, 1},  4, 4,
587       32, {{0}, {16}, {16}, {0}},
588       {{0}, {16}, {0}, {0}}},
589 
590    {SVGA3D_R32_TYPELESS, SVGA3DBLOCKDESC_RED,
591       {1, 1, 1},  4, 4,
592       32, {{0}, {0}, {32}, {0}},
593       {{0}, {0}, {0}, {0}}},
594 
595    {SVGA3D_D32_FLOAT, SVGA3DBLOCKDESC_DEPTH,
596       {1, 1, 1},  4, 4,
597       32, {{0}, {0}, {32}, {0}},
598       {{0}, {0}, {0}, {0}}},
599 
600    {SVGA3D_R32_UINT, SVGA3DBLOCKDESC_RED,
601       {1, 1, 1},  4, 4,
602       32, {{0}, {0}, {32}, {0}},
603       {{0}, {0}, {0}, {0}}},
604 
605    {SVGA3D_R32_SINT, SVGA3DBLOCKDESC_RED,
606       {1, 1, 1},  4, 4,
607       32, {{0}, {0}, {32}, {0}},
608       {{0}, {0}, {0}, {0}}},
609 
610    {SVGA3D_R24G8_TYPELESS, SVGA3DBLOCKDESC_RG,
611       {1, 1, 1},  4, 4,
612       32, {{0}, {8}, {24}, {0}},
613       {{0}, {24}, {0}, {0}}},
614 
615    {SVGA3D_D24_UNORM_S8_UINT, SVGA3DBLOCKDESC_DS,
616       {1, 1, 1},  4, 4,
617       32, {{0}, {8}, {24}, {0}},
618       {{0}, {24}, {0}, {0}}},
619 
620    {SVGA3D_R24_UNORM_X8_TYPELESS, SVGA3DBLOCKDESC_RED,
621       {1, 1, 1},  4, 4,
622       32, {{0}, {0}, {24}, {0}},
623       {{0}, {0}, {0}, {0}}},
624 
625    {SVGA3D_X24_TYPELESS_G8_UINT, SVGA3DBLOCKDESC_GREEN,
626       {1, 1, 1},  4, 4,
627       32, {{0}, {8}, {0}, {0}},
628       {{0}, {24}, {0}, {0}}},
629 
630    {SVGA3D_R8G8_TYPELESS, SVGA3DBLOCKDESC_RG,
631       {1, 1, 1},  2, 2,
632       16, {{0}, {8}, {8}, {0}},
633       {{0}, {8}, {0}, {0}}},
634 
635    {SVGA3D_R8G8_UNORM, SVGA3DBLOCKDESC_RG,
636       {1, 1, 1},  2, 2,
637       16, {{0}, {8}, {8}, {0}},
638       {{0}, {8}, {0}, {0}}},
639 
640    {SVGA3D_R8G8_UINT, SVGA3DBLOCKDESC_RG,
641       {1, 1, 1},  2, 2,
642       16, {{0}, {8}, {8}, {0}},
643       {{0}, {8}, {0}, {0}}},
644 
645    {SVGA3D_R8G8_SINT, SVGA3DBLOCKDESC_UV,
646       {1, 1, 1},  2, 2,
647       16, {{0}, {8}, {8}, {0}},
648       {{0}, {8}, {0}, {0}}},
649 
650    {SVGA3D_R16_TYPELESS, SVGA3DBLOCKDESC_RED,
651       {1, 1, 1},  2, 2,
652       16, {{0}, {0}, {16}, {0}},
653       {{0}, {0}, {0}, {0}}},
654 
655    {SVGA3D_R16_UNORM, SVGA3DBLOCKDESC_RED,
656       {1, 1, 1},  2, 2,
657       16, {{0}, {0}, {16}, {0}},
658       {{0}, {0}, {0}, {0}}},
659 
660    {SVGA3D_R16_UINT, SVGA3DBLOCKDESC_RED,
661       {1, 1, 1},  2, 2,
662       16, {{0}, {0}, {16}, {0}},
663       {{0}, {0}, {0}, {0}}},
664 
665    {SVGA3D_R16_SNORM, SVGA3DBLOCKDESC_U,
666       {1, 1, 1},  2, 2,
667       16, {{0}, {0}, {16}, {0}},
668       {{0}, {0}, {0}, {0}}},
669 
670    {SVGA3D_R16_SINT, SVGA3DBLOCKDESC_U,
671       {1, 1, 1},  2, 2,
672       16, {{0}, {0}, {16}, {0}},
673       {{0}, {0}, {0}, {0}}},
674 
675    {SVGA3D_R8_TYPELESS, SVGA3DBLOCKDESC_RED,
676       {1, 1, 1},  1, 1,
677       8, {{0}, {0}, {8}, {0}},
678       {{0}, {0}, {0}, {0}}},
679 
680    {SVGA3D_R8_UNORM, SVGA3DBLOCKDESC_RED,
681       {1, 1, 1},  1, 1,
682       8, {{0}, {0}, {8}, {0}},
683       {{0}, {0}, {0}, {0}}},
684 
685    {SVGA3D_R8_UINT, SVGA3DBLOCKDESC_RED,
686       {1, 1, 1},  1, 1,
687       8, {{0}, {0}, {8}, {0}},
688       {{0}, {0}, {0}, {0}}},
689 
690    {SVGA3D_R8_SNORM, SVGA3DBLOCKDESC_U,
691       {1, 1, 1},  1, 1,
692       8, {{0}, {0}, {8}, {0}},
693       {{0}, {0}, {0}, {0}}},
694 
695    {SVGA3D_R8_SINT, SVGA3DBLOCKDESC_U,
696       {1, 1, 1},  1, 1,
697       8, {{0}, {0}, {8}, {0}},
698       {{0}, {0}, {0}, {0}}},
699 
700    {SVGA3D_P8, SVGA3DBLOCKDESC_RED,
701       {1, 1, 1},  1, 1,
702       8, {{0}, {0}, {8}, {0}},
703       {{0}, {0}, {0}, {0}}},
704 
705    {SVGA3D_R9G9B9E5_SHAREDEXP, SVGA3DBLOCKDESC_RGBE,
706       {1, 1, 1},  4, 4,
707       32, {{9}, {9}, {9}, {5}},
708       {{18}, {9}, {0}, {27}}},
709 
710    {SVGA3D_R8G8_B8G8_UNORM, SVGA3DBLOCKDESC_RG,
711       {1, 1, 1},  2, 2,
712       16, {{0}, {8}, {8}, {0}},
713       {{0}, {8}, {0}, {0}}},
714 
715    {SVGA3D_G8R8_G8B8_UNORM, SVGA3DBLOCKDESC_RG,
716       {1, 1, 1},  2, 2,
717       16, {{0}, {8}, {8}, {0}},
718       {{0}, {8}, {0}, {0}}},
719 
720    {SVGA3D_BC1_TYPELESS, SVGA3DBLOCKDESC_COMPRESSED,
721       {4, 4, 1},  8, 8,
722       64, {{0}, {0}, {64}, {0}},
723       {{0}, {0}, {0}, {0}}},
724 
725    {SVGA3D_BC1_UNORM_SRGB, SVGA3DBLOCKDESC_COMPRESSED_SRGB,
726       {4, 4, 1},  8, 8,
727       64, {{0}, {0}, {64}, {0}},
728       {{0}, {0}, {0}, {0}}},
729 
730    {SVGA3D_BC2_TYPELESS, SVGA3DBLOCKDESC_COMPRESSED,
731       {4, 4, 1},  16, 16,
732       128, {{0}, {0}, {128}, {0}},
733       {{0}, {0}, {0}, {0}}},
734 
735    {SVGA3D_BC2_UNORM_SRGB, SVGA3DBLOCKDESC_COMPRESSED_SRGB,
736       {4, 4, 1},  16, 16,
737       128, {{0}, {0}, {128}, {0}},
738       {{0}, {0}, {0}, {0}}},
739 
740    {SVGA3D_BC3_TYPELESS, SVGA3DBLOCKDESC_COMPRESSED,
741       {4, 4, 1},  16, 16,
742       128, {{0}, {0}, {128}, {0}},
743       {{0}, {0}, {0}, {0}}},
744 
745    {SVGA3D_BC3_UNORM_SRGB, SVGA3DBLOCKDESC_COMPRESSED_SRGB,
746       {4, 4, 1},  16, 16,
747       128, {{0}, {0}, {128}, {0}},
748       {{0}, {0}, {0}, {0}}},
749 
750    {SVGA3D_BC4_TYPELESS, SVGA3DBLOCKDESC_COMPRESSED,
751       {4, 4, 1},  8, 8,
752       64, {{0}, {0}, {64}, {0}},
753       {{0}, {0}, {0}, {0}}},
754 
755    {SVGA3D_ATI1, SVGA3DBLOCKDESC_COMPRESSED,
756       {4, 4, 1},  8, 8,
757       64, {{0}, {0}, {64}, {0}},
758       {{0}, {0}, {0}, {0}}},
759 
760    {SVGA3D_BC4_SNORM, SVGA3DBLOCKDESC_COMPRESSED,
761       {4, 4, 1},  8, 8,
762       64, {{0}, {0}, {64}, {0}},
763       {{0}, {0}, {0}, {0}}},
764 
765    {SVGA3D_BC5_TYPELESS, SVGA3DBLOCKDESC_COMPRESSED,
766       {4, 4, 1},  16, 16,
767       128, {{0}, {0}, {128}, {0}},
768       {{0}, {0}, {0}, {0}}},
769 
770    {SVGA3D_ATI2, SVGA3DBLOCKDESC_COMPRESSED,
771       {4, 4, 1},  16, 16,
772       128, {{0}, {0}, {128}, {0}},
773       {{0}, {0}, {0}, {0}}},
774 
775    {SVGA3D_BC5_SNORM, SVGA3DBLOCKDESC_COMPRESSED,
776       {4, 4, 1},  16, 16,
777       128, {{0}, {0}, {128}, {0}},
778       {{0}, {0}, {0}, {0}}},
779 
780    {SVGA3D_R10G10B10_XR_BIAS_A2_UNORM, SVGA3DBLOCKDESC_RGBA,
781       {1, 1, 1},  4, 4,
782       32, {{10}, {10}, {10}, {2}},
783       {{0}, {10}, {20}, {30}}},
784 
785    {SVGA3D_B8G8R8A8_TYPELESS, SVGA3DBLOCKDESC_RGBA,
786       {1, 1, 1},  4, 4,
787       32, {{8}, {8}, {8}, {8}},
788       {{0}, {8}, {16}, {24}}},
789 
790    {SVGA3D_B8G8R8A8_UNORM_SRGB, SVGA3DBLOCKDESC_RGBA_SRGB,
791       {1, 1, 1},  4, 4,
792       32, {{8}, {8}, {8}, {8}},
793       {{0}, {8}, {16}, {24}}},
794 
795    {SVGA3D_B8G8R8X8_TYPELESS, SVGA3DBLOCKDESC_RGB,
796       {1, 1, 1},  4, 4,
797       24, {{8}, {8}, {8}, {0}},
798       {{0}, {8}, {16}, {24}}},
799 
800    {SVGA3D_B8G8R8X8_UNORM_SRGB, SVGA3DBLOCKDESC_RGB_SRGB,
801       {1, 1, 1},  4, 4,
802       24, {{8}, {8}, {8}, {0}},
803       {{0}, {8}, {16}, {24}}},
804 
805    {SVGA3D_Z_DF16, SVGA3DBLOCKDESC_DEPTH,
806       {1, 1, 1},  2, 2,
807       16, {{0}, {0}, {16}, {0}},
808       {{0}, {0}, {0}, {0}}},
809 
810    {SVGA3D_Z_DF24, SVGA3DBLOCKDESC_DEPTH,
811       {1, 1, 1},  4, 4,
812       32, {{0}, {8}, {24}, {0}},
813       {{0}, {24}, {0}, {0}}},
814 
815    {SVGA3D_Z_D24S8_INT, SVGA3DBLOCKDESC_DS,
816       {1, 1, 1},  4, 4,
817       32, {{0}, {8}, {24}, {0}},
818       {{0}, {24}, {0}, {0}}},
819 
820    {SVGA3D_YV12, SVGA3DBLOCKDESC_YV12,
821       {2, 2, 1},  6, 2,
822       48, {{0}, {0}, {48}, {0}},
823       {{0}, {0}, {0}, {0}}},
824 
825    {SVGA3D_R32G32B32A32_FLOAT, SVGA3DBLOCKDESC_RGBA_FP,
826       {1, 1, 1},  16, 16,
827       128, {{32}, {32}, {32}, {32}},
828       {{64}, {32}, {0}, {96}}},
829 
830    {SVGA3D_R16G16B16A16_FLOAT, SVGA3DBLOCKDESC_RGBA_FP,
831       {1, 1, 1},  8, 8,
832       64, {{16}, {16}, {16}, {16}},
833       {{32}, {16}, {0}, {48}}},
834 
835    {SVGA3D_R16G16B16A16_UNORM, SVGA3DBLOCKDESC_RGBA,
836       {1, 1, 1},  8, 8,
837       64, {{16}, {16}, {16}, {16}},
838       {{32}, {16}, {0}, {48}}},
839 
840    {SVGA3D_R32G32_FLOAT, SVGA3DBLOCKDESC_RG_FP,
841       {1, 1, 1},  8, 8,
842       64, {{0}, {32}, {32}, {0}},
843       {{0}, {32}, {0}, {0}}},
844 
845    {SVGA3D_R10G10B10A2_UNORM, SVGA3DBLOCKDESC_RGBA,
846       {1, 1, 1},  4, 4,
847       32, {{10}, {10}, {10}, {2}},
848       {{0}, {10}, {20}, {30}}},
849 
850    {SVGA3D_R8G8B8A8_SNORM, SVGA3DBLOCKDESC_RGBA,
851       {1, 1, 1},  4, 4,
852       32, {{8}, {8}, {8}, {8}},
853       {{24}, {16}, {8}, {0}}},
854 
855    {SVGA3D_R16G16_FLOAT, SVGA3DBLOCKDESC_RG_FP,
856       {1, 1, 1},  4, 4,
857       32, {{0}, {16}, {16}, {0}},
858       {{0}, {16}, {0}, {0}}},
859 
860    {SVGA3D_R16G16_UNORM, SVGA3DBLOCKDESC_RG,
861       {1, 1, 1},  4, 4,
862       32, {{0}, {16}, {16}, {0}},
863       {{0}, {0}, {16}, {0}}},
864 
865    {SVGA3D_R16G16_SNORM, SVGA3DBLOCKDESC_RG,
866       {1, 1, 1},  4, 4,
867       32, {{16}, {16}, {0}, {0}},
868       {{16}, {0}, {0}, {0}}},
869 
870    {SVGA3D_R32_FLOAT, SVGA3DBLOCKDESC_R_FP,
871       {1, 1, 1},  4, 4,
872       32, {{0}, {0}, {32}, {0}},
873       {{0}, {0}, {0}, {0}}},
874 
875    {SVGA3D_R8G8_SNORM, SVGA3DBLOCKDESC_RG,
876       {1, 1, 1},  2, 2,
877       16, {{8}, {8}, {0}, {0}},
878       {{8}, {0}, {0}, {0}}},
879 
880    {SVGA3D_R16_FLOAT, SVGA3DBLOCKDESC_R_FP,
881       {1, 1, 1},  2, 2,
882       16, {{0}, {0}, {16}, {0}},
883       {{0}, {0}, {0}, {0}}},
884 
885    {SVGA3D_D16_UNORM, SVGA3DBLOCKDESC_DEPTH,
886       {1, 1, 1},  2, 2,
887       16, {{0}, {0}, {16}, {0}},
888       {{0}, {0}, {0}, {0}}},
889 
890    {SVGA3D_A8_UNORM, SVGA3DBLOCKDESC_ALPHA,
891       {1, 1, 1},  1, 1,
892       8, {{0}, {0}, {0}, {8}},
893       {{0}, {0}, {0}, {0}}},
894 
895    {SVGA3D_BC1_UNORM, SVGA3DBLOCKDESC_COMPRESSED,
896       {4, 4, 1},  8, 8,
897       64, {{0}, {0}, {64}, {0}},
898       {{0}, {0}, {0}, {0}}},
899 
900    {SVGA3D_BC2_UNORM, SVGA3DBLOCKDESC_COMPRESSED,
901       {4, 4, 1},  16, 16,
902       128, {{0}, {0}, {128}, {0}},
903       {{0}, {0}, {0}, {0}}},
904 
905    {SVGA3D_BC3_UNORM, SVGA3DBLOCKDESC_COMPRESSED,
906       {4, 4, 1},  16, 16,
907       128, {{0}, {0}, {128}, {0}},
908       {{0}, {0}, {0}, {0}}},
909 
910    {SVGA3D_B5G6R5_UNORM, SVGA3DBLOCKDESC_RGB,
911       {1, 1, 1},  2, 2,
912       16, {{5}, {6}, {5}, {0}},
913       {{0}, {5}, {11}, {0}}},
914 
915    {SVGA3D_B5G5R5A1_UNORM, SVGA3DBLOCKDESC_RGBA,
916       {1, 1, 1},  2, 2,
917       16, {{5}, {5}, {5}, {1}},
918       {{0}, {5}, {10}, {15}}},
919 
920    {SVGA3D_B8G8R8A8_UNORM, SVGA3DBLOCKDESC_RGBA,
921       {1, 1, 1},  4, 4,
922       32, {{8}, {8}, {8}, {8}},
923       {{0}, {8}, {16}, {24}}},
924 
925    {SVGA3D_B8G8R8X8_UNORM, SVGA3DBLOCKDESC_RGB,
926       {1, 1, 1},  4, 4,
927       24, {{8}, {8}, {8}, {0}},
928       {{0}, {8}, {16}, {24}}},
929 
930    {SVGA3D_BC4_UNORM, SVGA3DBLOCKDESC_COMPRESSED,
931       {4, 4, 1},  8, 8,
932       64, {{0}, {0}, {64}, {0}},
933       {{0}, {0}, {0}, {0}}},
934 
935    {SVGA3D_BC5_UNORM, SVGA3DBLOCKDESC_COMPRESSED,
936       {4, 4, 1},  16, 16,
937       128, {{0}, {0}, {128}, {0}},
938       {{0}, {0}, {0}, {0}}},
939 
940 };
941 
942 static inline u32 clamped_umul32(u32 a, u32 b)
943 {
944 	uint64_t tmp = (uint64_t) a*b;
945 	return (tmp > (uint64_t) ((u32) -1)) ? (u32) -1 : tmp;
946 }
947 
948 static inline const struct svga3d_surface_desc *
949 svga3dsurface_get_desc(SVGA3dSurfaceFormat format)
950 {
951 	if (format < ARRAY_SIZE(svga3d_surface_descs))
952 		return &svga3d_surface_descs[format];
953 
954 	return &svga3d_surface_descs[SVGA3D_FORMAT_INVALID];
955 }
956 
957 /*
958  *----------------------------------------------------------------------
959  *
960  * svga3dsurface_get_mip_size --
961  *
962  *      Given a base level size and the mip level, compute the size of
963  *      the mip level.
964  *
965  * Results:
966  *      See above.
967  *
968  * Side effects:
969  *      None.
970  *
971  *----------------------------------------------------------------------
972  */
973 
974 static inline surf_size_struct
975 svga3dsurface_get_mip_size(surf_size_struct base_level, u32 mip_level)
976 {
977 	surf_size_struct size;
978 
979 	size.width = max_t(u32, base_level.width >> mip_level, 1);
980 	size.height = max_t(u32, base_level.height >> mip_level, 1);
981 	size.depth = max_t(u32, base_level.depth >> mip_level, 1);
982 	return size;
983 }
984 
985 static inline void
986 svga3dsurface_get_size_in_blocks(const struct svga3d_surface_desc *desc,
987 				 const surf_size_struct *pixel_size,
988 				 surf_size_struct *block_size)
989 {
990 	block_size->width = DIV_ROUND_UP(pixel_size->width,
991 					 desc->block_size.width);
992 	block_size->height = DIV_ROUND_UP(pixel_size->height,
993 					  desc->block_size.height);
994 	block_size->depth = DIV_ROUND_UP(pixel_size->depth,
995 					 desc->block_size.depth);
996 }
997 
998 static inline bool
999 svga3dsurface_is_planar_surface(const struct svga3d_surface_desc *desc)
1000 {
1001 	return (desc->block_desc & SVGA3DBLOCKDESC_PLANAR_YUV) != 0;
1002 }
1003 
1004 static inline u32
1005 svga3dsurface_calculate_pitch(const struct svga3d_surface_desc *desc,
1006 			      const surf_size_struct *size)
1007 {
1008 	u32 pitch;
1009 	surf_size_struct blocks;
1010 
1011 	svga3dsurface_get_size_in_blocks(desc, size, &blocks);
1012 
1013 	pitch = blocks.width * desc->pitch_bytes_per_block;
1014 
1015 	return pitch;
1016 }
1017 
1018 /*
1019  *-----------------------------------------------------------------------------
1020  *
1021  * svga3dsurface_get_image_buffer_size --
1022  *
1023  *      Return the number of bytes of buffer space required to store
1024  *      one image of a surface, optionally using the specified pitch.
1025  *
1026  *      If pitch is zero, it is assumed that rows are tightly packed.
1027  *
1028  *      This function is overflow-safe. If the result would have
1029  *      overflowed, instead we return MAX_UINT32.
1030  *
1031  * Results:
1032  *      Byte count.
1033  *
1034  * Side effects:
1035  *      None.
1036  *
1037  *-----------------------------------------------------------------------------
1038  */
1039 
1040 static inline u32
1041 svga3dsurface_get_image_buffer_size(const struct svga3d_surface_desc *desc,
1042 				    const surf_size_struct *size,
1043 				    u32 pitch)
1044 {
1045 	surf_size_struct image_blocks;
1046 	u32 slice_size, total_size;
1047 
1048 	svga3dsurface_get_size_in_blocks(desc, size, &image_blocks);
1049 
1050 	if (svga3dsurface_is_planar_surface(desc)) {
1051 		total_size = clamped_umul32(image_blocks.width,
1052 					    image_blocks.height);
1053 		total_size = clamped_umul32(total_size, image_blocks.depth);
1054 		total_size = clamped_umul32(total_size, desc->bytes_per_block);
1055 		return total_size;
1056 	}
1057 
1058 	if (pitch == 0)
1059 		pitch = svga3dsurface_calculate_pitch(desc, size);
1060 
1061 	slice_size = clamped_umul32(image_blocks.height, pitch);
1062 	total_size = clamped_umul32(slice_size, image_blocks.depth);
1063 
1064 	return total_size;
1065 }
1066 
1067 static inline u32
1068 svga3dsurface_get_serialized_size(SVGA3dSurfaceFormat format,
1069 				  surf_size_struct base_level_size,
1070 				  u32 num_mip_levels,
1071 				  u32 num_layers)
1072 {
1073 	const struct svga3d_surface_desc *desc = svga3dsurface_get_desc(format);
1074 	u32 total_size = 0;
1075 	u32 mip;
1076 
1077 	for (mip = 0; mip < num_mip_levels; mip++) {
1078 		surf_size_struct size =
1079 			svga3dsurface_get_mip_size(base_level_size, mip);
1080 		total_size += svga3dsurface_get_image_buffer_size(desc,
1081 								  &size, 0);
1082 	}
1083 
1084 	return total_size * num_layers;
1085 }
1086 
1087 
1088 /**
1089  * svga3dsurface_get_pixel_offset - Compute the offset (in bytes) to a pixel
1090  * in an image (or volume).
1091  *
1092  * @width: The image width in pixels.
1093  * @height: The image height in pixels
1094  */
1095 static inline u32
1096 svga3dsurface_get_pixel_offset(SVGA3dSurfaceFormat format,
1097 			       u32 width, u32 height,
1098 			       u32 x, u32 y, u32 z)
1099 {
1100 	const struct svga3d_surface_desc *desc = svga3dsurface_get_desc(format);
1101 	const u32 bw = desc->block_size.width, bh = desc->block_size.height;
1102 	const u32 bd = desc->block_size.depth;
1103 	const u32 rowstride = DIV_ROUND_UP(width, bw) * desc->bytes_per_block;
1104 	const u32 imgstride = DIV_ROUND_UP(height, bh) * rowstride;
1105 	const u32 offset = (z / bd * imgstride +
1106 			    y / bh * rowstride +
1107 			    x / bw * desc->bytes_per_block);
1108 	return offset;
1109 }
1110 
1111 
1112 static inline u32
1113 svga3dsurface_get_image_offset(SVGA3dSurfaceFormat format,
1114 			       surf_size_struct baseLevelSize,
1115 			       u32 numMipLevels,
1116 			       u32 face,
1117 			       u32 mip)
1118 
1119 {
1120 	u32 offset;
1121 	u32 mipChainBytes;
1122 	u32 mipChainBytesToLevel;
1123 	u32 i;
1124 	const struct svga3d_surface_desc *desc;
1125 	surf_size_struct mipSize;
1126 	u32 bytes;
1127 
1128 	desc = svga3dsurface_get_desc(format);
1129 
1130 	mipChainBytes = 0;
1131 	mipChainBytesToLevel = 0;
1132 	for (i = 0; i < numMipLevels; i++) {
1133 		mipSize = svga3dsurface_get_mip_size(baseLevelSize, i);
1134 		bytes = svga3dsurface_get_image_buffer_size(desc, &mipSize, 0);
1135 		mipChainBytes += bytes;
1136 		if (i < mip)
1137 			mipChainBytesToLevel += bytes;
1138 	}
1139 
1140 	offset = mipChainBytes * face + mipChainBytesToLevel;
1141 
1142 	return offset;
1143 }
1144 
1145 
1146 /**
1147  * svga3dsurface_is_gb_screen_target_format - Is the specified format usable as
1148  *                                            a ScreenTarget?
1149  *                                            (with just the GBObjects cap-bit
1150  *                                             set)
1151  * @format: format to queried
1152  *
1153  * RETURNS:
1154  * true if queried format is valid for screen targets
1155  */
1156 static inline bool
1157 svga3dsurface_is_gb_screen_target_format(SVGA3dSurfaceFormat format)
1158 {
1159 	return (format == SVGA3D_X8R8G8B8 ||
1160 		format == SVGA3D_A8R8G8B8 ||
1161 		format == SVGA3D_R5G6B5   ||
1162 		format == SVGA3D_X1R5G5B5 ||
1163 		format == SVGA3D_A1R5G5B5 ||
1164 		format == SVGA3D_P8);
1165 }
1166 
1167 
1168 /**
1169  * svga3dsurface_is_dx_screen_target_format - Is the specified format usable as
1170  *                                            a ScreenTarget?
1171  *                                            (with DX10 enabled)
1172  *
1173  * @format: format to queried
1174  *
1175  * Results:
1176  * true if queried format is valid for screen targets
1177  */
1178 static inline bool
1179 svga3dsurface_is_dx_screen_target_format(SVGA3dSurfaceFormat format)
1180 {
1181 	return (format == SVGA3D_R8G8B8A8_UNORM ||
1182 		format == SVGA3D_B8G8R8A8_UNORM ||
1183 		format == SVGA3D_B8G8R8X8_UNORM);
1184 }
1185 
1186 
1187 /**
1188  * svga3dsurface_is_screen_target_format - Is the specified format usable as a
1189  *                                         ScreenTarget?
1190  *                                         (for some combination of caps)
1191  *
1192  * @format: format to queried
1193  *
1194  * Results:
1195  * true if queried format is valid for screen targets
1196  */
1197 static inline bool
1198 svga3dsurface_is_screen_target_format(SVGA3dSurfaceFormat format)
1199 {
1200 	if (svga3dsurface_is_gb_screen_target_format(format)) {
1201 		return true;
1202 	}
1203 	return svga3dsurface_is_dx_screen_target_format(format);
1204 }
1205