1 /**************************************************************************
3 * Copyright © 2008-2015 VMware, Inc., Palo Alto, CA., USA
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 #include <linux/kernel.h>
32 #include <drm/vmwgfx_drm.h>
33 #define surf_size_struct struct drm_vmw_size
35 #else /* __KERNEL__ */
38 #define ARRAY_SIZE(_A) (sizeof(_A) / sizeof((_A)[0]))
39 #endif /* ARRAY_SIZE */
41 #define max_t(type, x, y) ((x) > (y) ? (x) : (y))
42 #define surf_size_struct SVGA3dSize
45 #endif /* __KERNEL__ */
47 #include "svga3d_reg.h"
50 * enum svga3d_block_desc describes the active data channels in a block.
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.
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.
65 * Note: Compressed and IEEE formats do not use the bitMask structure.
68 enum svga3d_block_desc
{
69 SVGA3DBLOCKDESC_NONE
= 0, /* No channels are active */
70 SVGA3DBLOCKDESC_BLUE
= 1 << 0, /* Block with red channel
72 SVGA3DBLOCKDESC_U
= 1 << 0, /* Block with bump U channel
74 SVGA3DBLOCKDESC_UV_VIDEO
= 1 << 7, /* Block with alternating video
76 SVGA3DBLOCKDESC_GREEN
= 1 << 1, /* Block with green channel
78 SVGA3DBLOCKDESC_V
= 1 << 1, /* Block with bump V channel
80 SVGA3DBLOCKDESC_STENCIL
= 1 << 1, /* Block with a stencil
82 SVGA3DBLOCKDESC_RED
= 1 << 2, /* Block with blue channel
84 SVGA3DBLOCKDESC_W
= 1 << 2, /* Block with bump W channel
86 SVGA3DBLOCKDESC_LUMINANCE
= 1 << 2, /* Block with luminance channel
88 SVGA3DBLOCKDESC_Y
= 1 << 2, /* Block with video luminance
90 SVGA3DBLOCKDESC_DEPTH
= 1 << 2, /* Block with depth channel */
91 SVGA3DBLOCKDESC_ALPHA
= 1 << 3, /* Block with an alpha
93 SVGA3DBLOCKDESC_Q
= 1 << 3, /* Block with bump Q channel
95 SVGA3DBLOCKDESC_BUFFER
= 1 << 4, /* Block stores 1 byte of
97 SVGA3DBLOCKDESC_COMPRESSED
= 1 << 5, /* Block stores n bytes of
99 compression method used */
100 SVGA3DBLOCKDESC_IEEE_FP
= 1 << 6, /* Block stores data in an IEEE
104 SVGA3DBLOCKDESC_PLANAR_YUV
= 1 << 8, /* Three separate blocks store
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,
112 SVGA3DBLOCKDESC_3PLANAR_YUV
= 1 << 14, /* 3 planes of separate
113 Y, U, V, e.g., YV12. */
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
|
127 SVGA3DBLOCKDESC_UVL
= SVGA3DBLOCKDESC_UV
|
128 SVGA3DBLOCKDESC_LUMINANCE
,
129 SVGA3DBLOCKDESC_UVW
= SVGA3DBLOCKDESC_UV
|
131 SVGA3DBLOCKDESC_UVWA
= SVGA3DBLOCKDESC_UVW
|
132 SVGA3DBLOCKDESC_ALPHA
,
133 SVGA3DBLOCKDESC_UVWQ
= SVGA3DBLOCKDESC_U
|
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
|
151 SVGA3DBLOCKDESC_AYUV
= SVGA3DBLOCKDESC_ALPHA
|
153 SVGA3DBLOCKDESC_U_VIDEO
|
154 SVGA3DBLOCKDESC_V_VIDEO
,
155 SVGA3DBLOCKDESC_RGBE
= SVGA3DBLOCKDESC_RGB
|
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
,
166 * SVGA3dSurfaceDesc describes the actual pixel data.
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).
175 struct svga3d_channel_def
{
203 struct svga3d_surface_desc
{
204 SVGA3dSurfaceFormat format
;
205 enum svga3d_block_desc block_desc
;
206 surf_size_struct block_size
;
208 u32 pitch_bytes_per_block
;
211 struct svga3d_channel_def bit_depth
;
212 struct svga3d_channel_def bit_offset
;
215 static const struct svga3d_surface_desc svga3d_surface_descs
[] = {
216 {SVGA3D_FORMAT_INVALID
, SVGA3DBLOCKDESC_NONE
,
218 0, {{0}, {0}, {0}, {0}},
219 {{0}, {0}, {0}, {0}}},
221 {SVGA3D_X8R8G8B8
, SVGA3DBLOCKDESC_RGB
,
223 24, {{8}, {8}, {8}, {0}},
224 {{0}, {8}, {16}, {24}}},
226 {SVGA3D_A8R8G8B8
, SVGA3DBLOCKDESC_RGBA
,
228 32, {{8}, {8}, {8}, {8}},
229 {{0}, {8}, {16}, {24}}},
231 {SVGA3D_R5G6B5
, SVGA3DBLOCKDESC_RGB
,
233 16, {{5}, {6}, {5}, {0}},
234 {{0}, {5}, {11}, {0}}},
236 {SVGA3D_X1R5G5B5
, SVGA3DBLOCKDESC_RGB
,
238 15, {{5}, {5}, {5}, {0}},
239 {{0}, {5}, {10}, {0}}},
241 {SVGA3D_A1R5G5B5
, SVGA3DBLOCKDESC_RGBA
,
243 16, {{5}, {5}, {5}, {1}},
244 {{0}, {5}, {10}, {15}}},
246 {SVGA3D_A4R4G4B4
, SVGA3DBLOCKDESC_RGBA
,
248 16, {{4}, {4}, {4}, {4}},
249 {{0}, {4}, {8}, {12}}},
251 {SVGA3D_Z_D32
, SVGA3DBLOCKDESC_DEPTH
,
253 32, {{0}, {0}, {32}, {0}},
254 {{0}, {0}, {0}, {0}}},
256 {SVGA3D_Z_D16
, SVGA3DBLOCKDESC_DEPTH
,
258 16, {{0}, {0}, {16}, {0}},
259 {{0}, {0}, {0}, {0}}},
261 {SVGA3D_Z_D24S8
, SVGA3DBLOCKDESC_DS
,
263 32, {{0}, {8}, {24}, {0}},
264 {{0}, {24}, {0}, {0}}},
266 {SVGA3D_Z_D15S1
, SVGA3DBLOCKDESC_DS
,
268 16, {{0}, {1}, {15}, {0}},
269 {{0}, {15}, {0}, {0}}},
271 {SVGA3D_LUMINANCE8
, SVGA3DBLOCKDESC_LUMINANCE
,
273 8, {{0}, {0}, {8}, {0}},
274 {{0}, {0}, {0}, {0}}},
276 {SVGA3D_LUMINANCE4_ALPHA4
, SVGA3DBLOCKDESC_LA
,
278 8, {{0}, {0}, {4}, {4}},
279 {{0}, {0}, {0}, {4}}},
281 {SVGA3D_LUMINANCE16
, SVGA3DBLOCKDESC_LUMINANCE
,
283 16, {{0}, {0}, {16}, {0}},
284 {{0}, {0}, {0}, {0}}},
286 {SVGA3D_LUMINANCE8_ALPHA8
, SVGA3DBLOCKDESC_LA
,
288 16, {{0}, {0}, {8}, {8}},
289 {{0}, {0}, {0}, {8}}},
291 {SVGA3D_DXT1
, SVGA3DBLOCKDESC_COMPRESSED
,
293 64, {{0}, {0}, {64}, {0}},
294 {{0}, {0}, {0}, {0}}},
296 {SVGA3D_DXT2
, SVGA3DBLOCKDESC_COMPRESSED
,
298 128, {{0}, {0}, {128}, {0}},
299 {{0}, {0}, {0}, {0}}},
301 {SVGA3D_DXT3
, SVGA3DBLOCKDESC_COMPRESSED
,
303 128, {{0}, {0}, {128}, {0}},
304 {{0}, {0}, {0}, {0}}},
306 {SVGA3D_DXT4
, SVGA3DBLOCKDESC_COMPRESSED
,
308 128, {{0}, {0}, {128}, {0}},
309 {{0}, {0}, {0}, {0}}},
311 {SVGA3D_DXT5
, SVGA3DBLOCKDESC_COMPRESSED
,
313 128, {{0}, {0}, {128}, {0}},
314 {{0}, {0}, {0}, {0}}},
316 {SVGA3D_BUMPU8V8
, SVGA3DBLOCKDESC_UV
,
318 16, {{0}, {0}, {8}, {8}},
319 {{0}, {0}, {0}, {8}}},
321 {SVGA3D_BUMPL6V5U5
, SVGA3DBLOCKDESC_UVL
,
323 16, {{5}, {5}, {6}, {0}},
324 {{11}, {6}, {0}, {0}}},
326 {SVGA3D_BUMPX8L8V8U8
, SVGA3DBLOCKDESC_UVL
,
328 32, {{8}, {8}, {8}, {0}},
329 {{16}, {8}, {0}, {0}}},
331 {SVGA3D_BUMPL8V8U8
, SVGA3DBLOCKDESC_UVL
,
333 24, {{8}, {8}, {8}, {0}},
334 {{16}, {8}, {0}, {0}}},
336 {SVGA3D_ARGB_S10E5
, SVGA3DBLOCKDESC_RGBA_FP
,
338 64, {{16}, {16}, {16}, {16}},
339 {{32}, {16}, {0}, {48}}},
341 {SVGA3D_ARGB_S23E8
, SVGA3DBLOCKDESC_RGBA_FP
,
343 128, {{32}, {32}, {32}, {32}},
344 {{64}, {32}, {0}, {96}}},
346 {SVGA3D_A2R10G10B10
, SVGA3DBLOCKDESC_RGBA
,
348 32, {{10}, {10}, {10}, {2}},
349 {{0}, {10}, {20}, {30}}},
351 {SVGA3D_V8U8
, SVGA3DBLOCKDESC_UV
,
353 16, {{8}, {8}, {0}, {0}},
354 {{8}, {0}, {0}, {0}}},
356 {SVGA3D_Q8W8V8U8
, SVGA3DBLOCKDESC_UVWQ
,
358 32, {{8}, {8}, {8}, {8}},
359 {{24}, {16}, {8}, {0}}},
361 {SVGA3D_CxV8U8
, SVGA3DBLOCKDESC_UV
,
363 16, {{8}, {8}, {0}, {0}},
364 {{8}, {0}, {0}, {0}}},
366 {SVGA3D_X8L8V8U8
, SVGA3DBLOCKDESC_UVL
,
368 24, {{8}, {8}, {8}, {0}},
369 {{16}, {8}, {0}, {0}}},
371 {SVGA3D_A2W10V10U10
, SVGA3DBLOCKDESC_UVWA
,
373 32, {{10}, {10}, {10}, {2}},
374 {{0}, {10}, {20}, {30}}},
376 {SVGA3D_ALPHA8
, SVGA3DBLOCKDESC_ALPHA
,
378 8, {{0}, {0}, {0}, {8}},
379 {{0}, {0}, {0}, {0}}},
381 {SVGA3D_R_S10E5
, SVGA3DBLOCKDESC_R_FP
,
383 16, {{0}, {0}, {16}, {0}},
384 {{0}, {0}, {0}, {0}}},
386 {SVGA3D_R_S23E8
, SVGA3DBLOCKDESC_R_FP
,
388 32, {{0}, {0}, {32}, {0}},
389 {{0}, {0}, {0}, {0}}},
391 {SVGA3D_RG_S10E5
, SVGA3DBLOCKDESC_RG_FP
,
393 32, {{0}, {16}, {16}, {0}},
394 {{0}, {16}, {0}, {0}}},
396 {SVGA3D_RG_S23E8
, SVGA3DBLOCKDESC_RG_FP
,
398 64, {{0}, {32}, {32}, {0}},
399 {{0}, {32}, {0}, {0}}},
401 {SVGA3D_BUFFER
, SVGA3DBLOCKDESC_BUFFER
,
403 8, {{0}, {0}, {8}, {0}},
404 {{0}, {0}, {0}, {0}}},
406 {SVGA3D_Z_D24X8
, SVGA3DBLOCKDESC_DEPTH
,
408 32, {{0}, {0}, {24}, {0}},
409 {{0}, {24}, {0}, {0}}},
411 {SVGA3D_V16U16
, SVGA3DBLOCKDESC_UV
,
413 32, {{16}, {16}, {0}, {0}},
414 {{16}, {0}, {0}, {0}}},
416 {SVGA3D_G16R16
, SVGA3DBLOCKDESC_RG
,
418 32, {{0}, {16}, {16}, {0}},
419 {{0}, {0}, {16}, {0}}},
421 {SVGA3D_A16B16G16R16
, SVGA3DBLOCKDESC_RGBA
,
423 64, {{16}, {16}, {16}, {16}},
424 {{32}, {16}, {0}, {48}}},
426 {SVGA3D_UYVY
, SVGA3DBLOCKDESC_YUV
,
428 16, {{8}, {0}, {8}, {0}},
429 {{0}, {0}, {8}, {0}}},
431 {SVGA3D_YUY2
, SVGA3DBLOCKDESC_YUV
,
433 16, {{8}, {0}, {8}, {0}},
434 {{8}, {0}, {0}, {0}}},
436 {SVGA3D_NV12
, SVGA3DBLOCKDESC_NV12
,
438 48, {{0}, {0}, {48}, {0}},
439 {{0}, {0}, {0}, {0}}},
441 {SVGA3D_AYUV
, SVGA3DBLOCKDESC_AYUV
,
443 32, {{8}, {8}, {8}, {8}},
444 {{0}, {8}, {16}, {24}}},
446 {SVGA3D_R32G32B32A32_TYPELESS
, SVGA3DBLOCKDESC_RGBA
,
448 128, {{32}, {32}, {32}, {32}},
449 {{64}, {32}, {0}, {96}}},
451 {SVGA3D_R32G32B32A32_UINT
, SVGA3DBLOCKDESC_RGBA
,
453 128, {{32}, {32}, {32}, {32}},
454 {{64}, {32}, {0}, {96}}},
456 {SVGA3D_R32G32B32A32_SINT
, SVGA3DBLOCKDESC_UVWQ
,
458 128, {{32}, {32}, {32}, {32}},
459 {{64}, {32}, {0}, {96}}},
461 {SVGA3D_R32G32B32_TYPELESS
, SVGA3DBLOCKDESC_RGB
,
463 96, {{32}, {32}, {32}, {0}},
464 {{64}, {32}, {0}, {0}}},
466 {SVGA3D_R32G32B32_FLOAT
, SVGA3DBLOCKDESC_RGB_FP
,
468 96, {{32}, {32}, {32}, {0}},
469 {{64}, {32}, {0}, {0}}},
471 {SVGA3D_R32G32B32_UINT
, SVGA3DBLOCKDESC_RGB
,
473 96, {{32}, {32}, {32}, {0}},
474 {{64}, {32}, {0}, {0}}},
476 {SVGA3D_R32G32B32_SINT
, SVGA3DBLOCKDESC_UVW
,
478 96, {{32}, {32}, {32}, {0}},
479 {{64}, {32}, {0}, {0}}},
481 {SVGA3D_R16G16B16A16_TYPELESS
, SVGA3DBLOCKDESC_RGBA
,
483 64, {{16}, {16}, {16}, {16}},
484 {{32}, {16}, {0}, {48}}},
486 {SVGA3D_R16G16B16A16_UINT
, SVGA3DBLOCKDESC_RGBA
,
488 64, {{16}, {16}, {16}, {16}},
489 {{32}, {16}, {0}, {48}}},
491 {SVGA3D_R16G16B16A16_SNORM
, SVGA3DBLOCKDESC_UVWQ
,
493 64, {{16}, {16}, {16}, {16}},
494 {{32}, {16}, {0}, {48}}},
496 {SVGA3D_R16G16B16A16_SINT
, SVGA3DBLOCKDESC_UVWQ
,
498 64, {{16}, {16}, {16}, {16}},
499 {{32}, {16}, {0}, {48}}},
501 {SVGA3D_R32G32_TYPELESS
, SVGA3DBLOCKDESC_RG
,
503 64, {{0}, {32}, {32}, {0}},
504 {{0}, {32}, {0}, {0}}},
506 {SVGA3D_R32G32_UINT
, SVGA3DBLOCKDESC_RG
,
508 64, {{0}, {32}, {32}, {0}},
509 {{0}, {32}, {0}, {0}}},
511 {SVGA3D_R32G32_SINT
, SVGA3DBLOCKDESC_UV
,
513 64, {{0}, {32}, {32}, {0}},
514 {{0}, {32}, {0}, {0}}},
516 {SVGA3D_R32G8X24_TYPELESS
, SVGA3DBLOCKDESC_RG
,
518 64, {{0}, {8}, {32}, {0}},
519 {{0}, {32}, {0}, {0}}},
521 {SVGA3D_D32_FLOAT_S8X24_UINT
, SVGA3DBLOCKDESC_DS
,
523 64, {{0}, {8}, {32}, {0}},
524 {{0}, {32}, {0}, {0}}},
526 {SVGA3D_R32_FLOAT_X8X24_TYPELESS
, SVGA3DBLOCKDESC_R_FP
,
528 64, {{0}, {0}, {32}, {0}},
529 {{0}, {0}, {0}, {0}}},
531 {SVGA3D_X32_TYPELESS_G8X24_UINT
, SVGA3DBLOCKDESC_GREEN
,
533 64, {{0}, {8}, {0}, {0}},
534 {{0}, {32}, {0}, {0}}},
536 {SVGA3D_R10G10B10A2_TYPELESS
, SVGA3DBLOCKDESC_RGBA
,
538 32, {{10}, {10}, {10}, {2}},
539 {{0}, {10}, {20}, {30}}},
541 {SVGA3D_R10G10B10A2_UINT
, SVGA3DBLOCKDESC_RGBA
,
543 32, {{10}, {10}, {10}, {2}},
544 {{0}, {10}, {20}, {30}}},
546 {SVGA3D_R11G11B10_FLOAT
, SVGA3DBLOCKDESC_RGB_FP
,
548 32, {{10}, {11}, {11}, {0}},
549 {{0}, {10}, {21}, {0}}},
551 {SVGA3D_R8G8B8A8_TYPELESS
, SVGA3DBLOCKDESC_RGBA
,
553 32, {{8}, {8}, {8}, {8}},
554 {{16}, {8}, {0}, {24}}},
556 {SVGA3D_R8G8B8A8_UNORM
, SVGA3DBLOCKDESC_RGBA
,
558 32, {{8}, {8}, {8}, {8}},
559 {{16}, {8}, {0}, {24}}},
561 {SVGA3D_R8G8B8A8_UNORM_SRGB
, SVGA3DBLOCKDESC_RGBA_SRGB
,
563 32, {{8}, {8}, {8}, {8}},
564 {{16}, {8}, {0}, {24}}},
566 {SVGA3D_R8G8B8A8_UINT
, SVGA3DBLOCKDESC_RGBA
,
568 32, {{8}, {8}, {8}, {8}},
569 {{16}, {8}, {0}, {24}}},
571 {SVGA3D_R8G8B8A8_SINT
, SVGA3DBLOCKDESC_RGBA
,
573 32, {{8}, {8}, {8}, {8}},
574 {{16}, {8}, {0}, {24}}},
576 {SVGA3D_R16G16_TYPELESS
, SVGA3DBLOCKDESC_RG
,
578 32, {{0}, {16}, {16}, {0}},
579 {{0}, {16}, {0}, {0}}},
581 {SVGA3D_R16G16_UINT
, SVGA3DBLOCKDESC_RG_FP
,
583 32, {{0}, {16}, {16}, {0}},
584 {{0}, {16}, {0}, {0}}},
586 {SVGA3D_R16G16_SINT
, SVGA3DBLOCKDESC_UV
,
588 32, {{0}, {16}, {16}, {0}},
589 {{0}, {16}, {0}, {0}}},
591 {SVGA3D_R32_TYPELESS
, SVGA3DBLOCKDESC_RED
,
593 32, {{0}, {0}, {32}, {0}},
594 {{0}, {0}, {0}, {0}}},
596 {SVGA3D_D32_FLOAT
, SVGA3DBLOCKDESC_DEPTH
,
598 32, {{0}, {0}, {32}, {0}},
599 {{0}, {0}, {0}, {0}}},
601 {SVGA3D_R32_UINT
, SVGA3DBLOCKDESC_RED
,
603 32, {{0}, {0}, {32}, {0}},
604 {{0}, {0}, {0}, {0}}},
606 {SVGA3D_R32_SINT
, SVGA3DBLOCKDESC_RED
,
608 32, {{0}, {0}, {32}, {0}},
609 {{0}, {0}, {0}, {0}}},
611 {SVGA3D_R24G8_TYPELESS
, SVGA3DBLOCKDESC_RG
,
613 32, {{0}, {8}, {24}, {0}},
614 {{0}, {24}, {0}, {0}}},
616 {SVGA3D_D24_UNORM_S8_UINT
, SVGA3DBLOCKDESC_DS
,
618 32, {{0}, {8}, {24}, {0}},
619 {{0}, {24}, {0}, {0}}},
621 {SVGA3D_R24_UNORM_X8_TYPELESS
, SVGA3DBLOCKDESC_RED
,
623 32, {{0}, {0}, {24}, {0}},
624 {{0}, {0}, {0}, {0}}},
626 {SVGA3D_X24_TYPELESS_G8_UINT
, SVGA3DBLOCKDESC_GREEN
,
628 32, {{0}, {8}, {0}, {0}},
629 {{0}, {24}, {0}, {0}}},
631 {SVGA3D_R8G8_TYPELESS
, SVGA3DBLOCKDESC_RG
,
633 16, {{0}, {8}, {8}, {0}},
634 {{0}, {8}, {0}, {0}}},
636 {SVGA3D_R8G8_UNORM
, SVGA3DBLOCKDESC_RG
,
638 16, {{0}, {8}, {8}, {0}},
639 {{0}, {8}, {0}, {0}}},
641 {SVGA3D_R8G8_UINT
, SVGA3DBLOCKDESC_RG
,
643 16, {{0}, {8}, {8}, {0}},
644 {{0}, {8}, {0}, {0}}},
646 {SVGA3D_R8G8_SINT
, SVGA3DBLOCKDESC_UV
,
648 16, {{0}, {8}, {8}, {0}},
649 {{0}, {8}, {0}, {0}}},
651 {SVGA3D_R16_TYPELESS
, SVGA3DBLOCKDESC_RED
,
653 16, {{0}, {0}, {16}, {0}},
654 {{0}, {0}, {0}, {0}}},
656 {SVGA3D_R16_UNORM
, SVGA3DBLOCKDESC_RED
,
658 16, {{0}, {0}, {16}, {0}},
659 {{0}, {0}, {0}, {0}}},
661 {SVGA3D_R16_UINT
, SVGA3DBLOCKDESC_RED
,
663 16, {{0}, {0}, {16}, {0}},
664 {{0}, {0}, {0}, {0}}},
666 {SVGA3D_R16_SNORM
, SVGA3DBLOCKDESC_U
,
668 16, {{0}, {0}, {16}, {0}},
669 {{0}, {0}, {0}, {0}}},
671 {SVGA3D_R16_SINT
, SVGA3DBLOCKDESC_U
,
673 16, {{0}, {0}, {16}, {0}},
674 {{0}, {0}, {0}, {0}}},
676 {SVGA3D_R8_TYPELESS
, SVGA3DBLOCKDESC_RED
,
678 8, {{0}, {0}, {8}, {0}},
679 {{0}, {0}, {0}, {0}}},
681 {SVGA3D_R8_UNORM
, SVGA3DBLOCKDESC_RED
,
683 8, {{0}, {0}, {8}, {0}},
684 {{0}, {0}, {0}, {0}}},
686 {SVGA3D_R8_UINT
, SVGA3DBLOCKDESC_RED
,
688 8, {{0}, {0}, {8}, {0}},
689 {{0}, {0}, {0}, {0}}},
691 {SVGA3D_R8_SNORM
, SVGA3DBLOCKDESC_U
,
693 8, {{0}, {0}, {8}, {0}},
694 {{0}, {0}, {0}, {0}}},
696 {SVGA3D_R8_SINT
, SVGA3DBLOCKDESC_U
,
698 8, {{0}, {0}, {8}, {0}},
699 {{0}, {0}, {0}, {0}}},
701 {SVGA3D_P8
, SVGA3DBLOCKDESC_RED
,
703 8, {{0}, {0}, {8}, {0}},
704 {{0}, {0}, {0}, {0}}},
706 {SVGA3D_R9G9B9E5_SHAREDEXP
, SVGA3DBLOCKDESC_RGBE
,
708 32, {{9}, {9}, {9}, {5}},
709 {{18}, {9}, {0}, {27}}},
711 {SVGA3D_R8G8_B8G8_UNORM
, SVGA3DBLOCKDESC_RG
,
713 16, {{0}, {8}, {8}, {0}},
714 {{0}, {8}, {0}, {0}}},
716 {SVGA3D_G8R8_G8B8_UNORM
, SVGA3DBLOCKDESC_RG
,
718 16, {{0}, {8}, {8}, {0}},
719 {{0}, {8}, {0}, {0}}},
721 {SVGA3D_BC1_TYPELESS
, SVGA3DBLOCKDESC_COMPRESSED
,
723 64, {{0}, {0}, {64}, {0}},
724 {{0}, {0}, {0}, {0}}},
726 {SVGA3D_BC1_UNORM_SRGB
, SVGA3DBLOCKDESC_COMPRESSED_SRGB
,
728 64, {{0}, {0}, {64}, {0}},
729 {{0}, {0}, {0}, {0}}},
731 {SVGA3D_BC2_TYPELESS
, SVGA3DBLOCKDESC_COMPRESSED
,
733 128, {{0}, {0}, {128}, {0}},
734 {{0}, {0}, {0}, {0}}},
736 {SVGA3D_BC2_UNORM_SRGB
, SVGA3DBLOCKDESC_COMPRESSED_SRGB
,
738 128, {{0}, {0}, {128}, {0}},
739 {{0}, {0}, {0}, {0}}},
741 {SVGA3D_BC3_TYPELESS
, SVGA3DBLOCKDESC_COMPRESSED
,
743 128, {{0}, {0}, {128}, {0}},
744 {{0}, {0}, {0}, {0}}},
746 {SVGA3D_BC3_UNORM_SRGB
, SVGA3DBLOCKDESC_COMPRESSED_SRGB
,
748 128, {{0}, {0}, {128}, {0}},
749 {{0}, {0}, {0}, {0}}},
751 {SVGA3D_BC4_TYPELESS
, SVGA3DBLOCKDESC_COMPRESSED
,
753 64, {{0}, {0}, {64}, {0}},
754 {{0}, {0}, {0}, {0}}},
756 {SVGA3D_ATI1
, SVGA3DBLOCKDESC_COMPRESSED
,
758 64, {{0}, {0}, {64}, {0}},
759 {{0}, {0}, {0}, {0}}},
761 {SVGA3D_BC4_SNORM
, SVGA3DBLOCKDESC_COMPRESSED
,
763 64, {{0}, {0}, {64}, {0}},
764 {{0}, {0}, {0}, {0}}},
766 {SVGA3D_BC5_TYPELESS
, SVGA3DBLOCKDESC_COMPRESSED
,
768 128, {{0}, {0}, {128}, {0}},
769 {{0}, {0}, {0}, {0}}},
771 {SVGA3D_ATI2
, SVGA3DBLOCKDESC_COMPRESSED
,
773 128, {{0}, {0}, {128}, {0}},
774 {{0}, {0}, {0}, {0}}},
776 {SVGA3D_BC5_SNORM
, SVGA3DBLOCKDESC_COMPRESSED
,
778 128, {{0}, {0}, {128}, {0}},
779 {{0}, {0}, {0}, {0}}},
781 {SVGA3D_R10G10B10_XR_BIAS_A2_UNORM
, SVGA3DBLOCKDESC_RGBA
,
783 32, {{10}, {10}, {10}, {2}},
784 {{0}, {10}, {20}, {30}}},
786 {SVGA3D_B8G8R8A8_TYPELESS
, SVGA3DBLOCKDESC_RGBA
,
788 32, {{8}, {8}, {8}, {8}},
789 {{0}, {8}, {16}, {24}}},
791 {SVGA3D_B8G8R8A8_UNORM_SRGB
, SVGA3DBLOCKDESC_RGBA_SRGB
,
793 32, {{8}, {8}, {8}, {8}},
794 {{0}, {8}, {16}, {24}}},
796 {SVGA3D_B8G8R8X8_TYPELESS
, SVGA3DBLOCKDESC_RGB
,
798 24, {{8}, {8}, {8}, {0}},
799 {{0}, {8}, {16}, {24}}},
801 {SVGA3D_B8G8R8X8_UNORM_SRGB
, SVGA3DBLOCKDESC_RGB_SRGB
,
803 24, {{8}, {8}, {8}, {0}},
804 {{0}, {8}, {16}, {24}}},
806 {SVGA3D_Z_DF16
, SVGA3DBLOCKDESC_DEPTH
,
808 16, {{0}, {0}, {16}, {0}},
809 {{0}, {0}, {0}, {0}}},
811 {SVGA3D_Z_DF24
, SVGA3DBLOCKDESC_DEPTH
,
813 32, {{0}, {8}, {24}, {0}},
814 {{0}, {24}, {0}, {0}}},
816 {SVGA3D_Z_D24S8_INT
, SVGA3DBLOCKDESC_DS
,
818 32, {{0}, {8}, {24}, {0}},
819 {{0}, {24}, {0}, {0}}},
821 {SVGA3D_YV12
, SVGA3DBLOCKDESC_YV12
,
823 48, {{0}, {0}, {48}, {0}},
824 {{0}, {0}, {0}, {0}}},
826 {SVGA3D_R32G32B32A32_FLOAT
, SVGA3DBLOCKDESC_RGBA_FP
,
828 128, {{32}, {32}, {32}, {32}},
829 {{64}, {32}, {0}, {96}}},
831 {SVGA3D_R16G16B16A16_FLOAT
, SVGA3DBLOCKDESC_RGBA_FP
,
833 64, {{16}, {16}, {16}, {16}},
834 {{32}, {16}, {0}, {48}}},
836 {SVGA3D_R16G16B16A16_UNORM
, SVGA3DBLOCKDESC_RGBA
,
838 64, {{16}, {16}, {16}, {16}},
839 {{32}, {16}, {0}, {48}}},
841 {SVGA3D_R32G32_FLOAT
, SVGA3DBLOCKDESC_RG_FP
,
843 64, {{0}, {32}, {32}, {0}},
844 {{0}, {32}, {0}, {0}}},
846 {SVGA3D_R10G10B10A2_UNORM
, SVGA3DBLOCKDESC_RGBA
,
848 32, {{10}, {10}, {10}, {2}},
849 {{0}, {10}, {20}, {30}}},
851 {SVGA3D_R8G8B8A8_SNORM
, SVGA3DBLOCKDESC_RGBA
,
853 32, {{8}, {8}, {8}, {8}},
854 {{24}, {16}, {8}, {0}}},
856 {SVGA3D_R16G16_FLOAT
, SVGA3DBLOCKDESC_RG_FP
,
858 32, {{0}, {16}, {16}, {0}},
859 {{0}, {16}, {0}, {0}}},
861 {SVGA3D_R16G16_UNORM
, SVGA3DBLOCKDESC_RG
,
863 32, {{0}, {16}, {16}, {0}},
864 {{0}, {0}, {16}, {0}}},
866 {SVGA3D_R16G16_SNORM
, SVGA3DBLOCKDESC_RG
,
868 32, {{16}, {16}, {0}, {0}},
869 {{16}, {0}, {0}, {0}}},
871 {SVGA3D_R32_FLOAT
, SVGA3DBLOCKDESC_R_FP
,
873 32, {{0}, {0}, {32}, {0}},
874 {{0}, {0}, {0}, {0}}},
876 {SVGA3D_R8G8_SNORM
, SVGA3DBLOCKDESC_RG
,
878 16, {{8}, {8}, {0}, {0}},
879 {{8}, {0}, {0}, {0}}},
881 {SVGA3D_R16_FLOAT
, SVGA3DBLOCKDESC_R_FP
,
883 16, {{0}, {0}, {16}, {0}},
884 {{0}, {0}, {0}, {0}}},
886 {SVGA3D_D16_UNORM
, SVGA3DBLOCKDESC_DEPTH
,
888 16, {{0}, {0}, {16}, {0}},
889 {{0}, {0}, {0}, {0}}},
891 {SVGA3D_A8_UNORM
, SVGA3DBLOCKDESC_ALPHA
,
893 8, {{0}, {0}, {0}, {8}},
894 {{0}, {0}, {0}, {0}}},
896 {SVGA3D_BC1_UNORM
, SVGA3DBLOCKDESC_COMPRESSED
,
898 64, {{0}, {0}, {64}, {0}},
899 {{0}, {0}, {0}, {0}}},
901 {SVGA3D_BC2_UNORM
, SVGA3DBLOCKDESC_COMPRESSED
,
903 128, {{0}, {0}, {128}, {0}},
904 {{0}, {0}, {0}, {0}}},
906 {SVGA3D_BC3_UNORM
, SVGA3DBLOCKDESC_COMPRESSED
,
908 128, {{0}, {0}, {128}, {0}},
909 {{0}, {0}, {0}, {0}}},
911 {SVGA3D_B5G6R5_UNORM
, SVGA3DBLOCKDESC_RGB
,
913 16, {{5}, {6}, {5}, {0}},
914 {{0}, {5}, {11}, {0}}},
916 {SVGA3D_B5G5R5A1_UNORM
, SVGA3DBLOCKDESC_RGBA
,
918 16, {{5}, {5}, {5}, {1}},
919 {{0}, {5}, {10}, {15}}},
921 {SVGA3D_B8G8R8A8_UNORM
, SVGA3DBLOCKDESC_RGBA
,
923 32, {{8}, {8}, {8}, {8}},
924 {{0}, {8}, {16}, {24}}},
926 {SVGA3D_B8G8R8X8_UNORM
, SVGA3DBLOCKDESC_RGB
,
928 24, {{8}, {8}, {8}, {0}},
929 {{0}, {8}, {16}, {24}}},
931 {SVGA3D_BC4_UNORM
, SVGA3DBLOCKDESC_COMPRESSED
,
933 64, {{0}, {0}, {64}, {0}},
934 {{0}, {0}, {0}, {0}}},
936 {SVGA3D_BC5_UNORM
, SVGA3DBLOCKDESC_COMPRESSED
,
938 128, {{0}, {0}, {128}, {0}},
939 {{0}, {0}, {0}, {0}}},
943 static inline u32
clamped_umul32(u32 a
, u32 b
)
945 uint64_t tmp
= (uint64_t) a
*b
;
946 return (tmp
> (uint64_t) ((u32
) -1)) ? (u32
) -1 : tmp
;
949 static inline const struct svga3d_surface_desc
*
950 svga3dsurface_get_desc(SVGA3dSurfaceFormat format
)
952 if (format
< ARRAY_SIZE(svga3d_surface_descs
))
953 return &svga3d_surface_descs
[format
];
955 return &svga3d_surface_descs
[SVGA3D_FORMAT_INVALID
];
959 *----------------------------------------------------------------------
961 * svga3dsurface_get_mip_size --
963 * Given a base level size and the mip level, compute the size of
972 *----------------------------------------------------------------------
975 static inline surf_size_struct
976 svga3dsurface_get_mip_size(surf_size_struct base_level
, u32 mip_level
)
978 surf_size_struct size
;
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);
989 svga3dsurface_get_size_in_blocks(const struct svga3d_surface_desc
*desc
,
990 const surf_size_struct
*pixel_size
,
991 surf_size_struct
*block_size
)
993 block_size
->width
= __KERNEL_DIV_ROUND_UP(pixel_size
->width
,
994 desc
->block_size
.width
);
995 block_size
->height
= __KERNEL_DIV_ROUND_UP(pixel_size
->height
,
996 desc
->block_size
.height
);
997 block_size
->depth
= __KERNEL_DIV_ROUND_UP(pixel_size
->depth
,
998 desc
->block_size
.depth
);
1002 svga3dsurface_is_planar_surface(const struct svga3d_surface_desc
*desc
)
1004 return (desc
->block_desc
& SVGA3DBLOCKDESC_PLANAR_YUV
) != 0;
1008 svga3dsurface_calculate_pitch(const struct svga3d_surface_desc
*desc
,
1009 const surf_size_struct
*size
)
1012 surf_size_struct blocks
;
1014 svga3dsurface_get_size_in_blocks(desc
, size
, &blocks
);
1016 pitch
= blocks
.width
* desc
->pitch_bytes_per_block
;
1022 *-----------------------------------------------------------------------------
1024 * svga3dsurface_get_image_buffer_size --
1026 * Return the number of bytes of buffer space required to store
1027 * one image of a surface, optionally using the specified pitch.
1029 * If pitch is zero, it is assumed that rows are tightly packed.
1031 * This function is overflow-safe. If the result would have
1032 * overflowed, instead we return MAX_UINT32.
1040 *-----------------------------------------------------------------------------
1044 svga3dsurface_get_image_buffer_size(const struct svga3d_surface_desc
*desc
,
1045 const surf_size_struct
*size
,
1048 surf_size_struct image_blocks
;
1049 u32 slice_size
, total_size
;
1051 svga3dsurface_get_size_in_blocks(desc
, size
, &image_blocks
);
1053 if (svga3dsurface_is_planar_surface(desc
)) {
1054 total_size
= clamped_umul32(image_blocks
.width
,
1055 image_blocks
.height
);
1056 total_size
= clamped_umul32(total_size
, image_blocks
.depth
);
1057 total_size
= clamped_umul32(total_size
, desc
->bytes_per_block
);
1062 pitch
= svga3dsurface_calculate_pitch(desc
, size
);
1064 slice_size
= clamped_umul32(image_blocks
.height
, pitch
);
1065 total_size
= clamped_umul32(slice_size
, image_blocks
.depth
);
1071 svga3dsurface_get_serialized_size(SVGA3dSurfaceFormat format
,
1072 surf_size_struct base_level_size
,
1076 const struct svga3d_surface_desc
*desc
= svga3dsurface_get_desc(format
);
1080 for (mip
= 0; mip
< num_mip_levels
; mip
++) {
1081 surf_size_struct size
=
1082 svga3dsurface_get_mip_size(base_level_size
, mip
);
1083 total_size
+= svga3dsurface_get_image_buffer_size(desc
,
1087 return total_size
* num_layers
;
1092 * svga3dsurface_get_pixel_offset - Compute the offset (in bytes) to a pixel
1093 * in an image (or volume).
1095 * @width: The image width in pixels.
1096 * @height: The image height in pixels
1099 svga3dsurface_get_pixel_offset(SVGA3dSurfaceFormat format
,
1100 u32 width
, u32 height
,
1101 u32 x
, u32 y
, u32 z
)
1103 const struct svga3d_surface_desc
*desc
= svga3dsurface_get_desc(format
);
1104 const u32 bw
= desc
->block_size
.width
, bh
= desc
->block_size
.height
;
1105 const u32 bd
= desc
->block_size
.depth
;
1106 const u32 rowstride
= __KERNEL_DIV_ROUND_UP(width
, bw
) *
1107 desc
->bytes_per_block
;
1108 const u32 imgstride
= __KERNEL_DIV_ROUND_UP(height
, bh
) * rowstride
;
1109 const u32 offset
= (z
/ bd
* imgstride
+
1110 y
/ bh
* rowstride
+
1111 x
/ bw
* desc
->bytes_per_block
);
1117 svga3dsurface_get_image_offset(SVGA3dSurfaceFormat format
,
1118 surf_size_struct baseLevelSize
,
1126 u32 mipChainBytesToLevel
;
1128 const struct svga3d_surface_desc
*desc
;
1129 surf_size_struct mipSize
;
1132 desc
= svga3dsurface_get_desc(format
);
1135 mipChainBytesToLevel
= 0;
1136 for (i
= 0; i
< numMipLevels
; i
++) {
1137 mipSize
= svga3dsurface_get_mip_size(baseLevelSize
, i
);
1138 bytes
= svga3dsurface_get_image_buffer_size(desc
, &mipSize
, 0);
1139 mipChainBytes
+= bytes
;
1141 mipChainBytesToLevel
+= bytes
;
1144 offset
= mipChainBytes
* face
+ mipChainBytesToLevel
;
1151 * svga3dsurface_is_gb_screen_target_format - Is the specified format usable as
1153 * (with just the GBObjects cap-bit
1155 * @format: format to queried
1158 * true if queried format is valid for screen targets
1161 svga3dsurface_is_gb_screen_target_format(SVGA3dSurfaceFormat format
)
1163 return (format
== SVGA3D_X8R8G8B8
||
1164 format
== SVGA3D_A8R8G8B8
||
1165 format
== SVGA3D_R5G6B5
||
1166 format
== SVGA3D_X1R5G5B5
||
1167 format
== SVGA3D_A1R5G5B5
||
1168 format
== SVGA3D_P8
);
1173 * svga3dsurface_is_dx_screen_target_format - Is the specified format usable as
1175 * (with DX10 enabled)
1177 * @format: format to queried
1180 * true if queried format is valid for screen targets
1183 svga3dsurface_is_dx_screen_target_format(SVGA3dSurfaceFormat format
)
1185 return (format
== SVGA3D_R8G8B8A8_UNORM
||
1186 format
== SVGA3D_B8G8R8A8_UNORM
||
1187 format
== SVGA3D_B8G8R8X8_UNORM
);
1192 * svga3dsurface_is_screen_target_format - Is the specified format usable as a
1194 * (for some combination of caps)
1196 * @format: format to queried
1199 * true if queried format is valid for screen targets
1202 svga3dsurface_is_screen_target_format(SVGA3dSurfaceFormat format
)
1204 if (svga3dsurface_is_gb_screen_target_format(format
)) {
1207 return svga3dsurface_is_dx_screen_target_format(format
);