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