Linux-libre 4.9.30-gnu
[librecmc/linux-libre.git] / drivers / gpu / drm / vmwgfx / device_include / svga3d_surfacedefs.h
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 }