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