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