1 /*==============================================================================
2 Copyright(c) 2017 Intel Corporation
3 
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files(the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and / or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21 ============================================================================*/
22 
23 #include "Internal/Common/GmmLibInc.h"
24 #ifdef _WIN32
25 #include <intrin.h>
26 #endif
27 
28 //64KB Undefined Swizzle Descriptors #########################################
29 // !! TODO (critical): Provide mapping helper function to UMD to map in non-TR
30 //                     Undefined64KBSwizzle resources. Also check if support
31 //                     for it is needed in GmmResCpuBlt.
32 //
33 // Note: These 64KB swizzles are not really hardware tile swizzles, so leave
34 //       them out of the CpuSwizzleBlt.c
35 
36 /*  On systems that do not support Std Swizzle (IGFX_GEN7_5_CORE / IGFX_GEN8_CORE),
37 we still have to support 64KB tiles. These 64KB tiles will be made of 16 4KB
38 tiles -- we'll be using TileY to create these 64KB tiles. The table below shows
39 how the 64KB tile shape changes depending on the bpp and how we need to arrange
40 (in columns X rows) the 4KB tiles to fit that shape.
41 
42     bpp     Tile Size (in pixels)   Tile Size (in bytes)      4K tile config
43     ---     --------------------    --------------------      --------------
44     8bpp        256x256                 256x256                     2x8
45     16bpp       256x128                 512x128                     4x4
46     32bpp       128x128                 512x128                     4x4
47     64bpp       128x64                  1024x64                     8x2
48     128bpp      64x64                   1024x64                     8x2
49 
50 We need 3 different swizzle pattern to support all configs above.  The swizzle
51 patterns are:
52 
53           |-Rows-|  |-Column-|   |-TileY Swizzle-|
54 8bpp:       YYY         X          XXXYYYYYXXXX
55 16/32bpp:   YY          XX         XXXYYYYYXXXX
56 64/128bpp:  Y           XXX        XXXYYYYYXXXX
57 
58 The translation of these Xs and Ys to bitmap is shown below */
59 extern const SWIZZLE_DESCRIPTOR INTEL_64KB_UNDEFINED_8bpp      = {0x1E0F, 0xE1F0, 0};
60 extern const SWIZZLE_DESCRIPTOR INTEL_64KB_UNDEFINED_16_32bpp  = {0x3E0F, 0xC1F0, 0};
61 extern const SWIZZLE_DESCRIPTOR INTEL_64KB_UNDEFINED_64_128bpp = {0x7E0F, 0x81F0, 0};
62 //#############################################################################
63 
64 //=============================================================================
65 // Function:
66 //    GmmIsRedecribedPlanes
67 //
68 // Description:
69 //     Checks if the resource has redescribed planes
70 //
71 // Arguments: <Look at Function Header)
72 //
73 // Return:
74 //    1 or 0
75 //-----------------------------------------------------------------------------
GmmIsRedecribedPlanes(GMM_RESOURCE_INFO * pGmmResource)76 uint8_t GMM_STDCALL GmmIsRedecribedPlanes(GMM_RESOURCE_INFO *pGmmResource)
77 {
78     return pGmmResource->GetResFlags().Info.RedecribedPlanes;
79 }
80 
81 //=============================================================================
82 // Function:
83 //    GmmGetLosslessCompressionType
84 //
85 // Description:
86 //     Returns the format's E2E compression format.
87 //
88 // Arguments: <Look at Function Header)
89 //
90 // Return:
91 //    GMM_E2ECOMP_FORMAT
92 //-----------------------------------------------------------------------------
GmmGetLosslessCompressionType(void * pLibContext,GMM_RESOURCE_FORMAT Format)93 uint8_t GMM_STDCALL GmmGetLosslessCompressionType(void *pLibContext, GMM_RESOURCE_FORMAT Format)
94 {
95     GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
96     __GMM_ASSERT((Format > GMM_FORMAT_INVALID) && (Format < GMM_RESOURCE_FORMATS));
97 
98     return pGmmLibContext->GetPlatformInfo().FormatTable[Format].CompressionFormat.AuxL1eFormat;
99 }
100 
101 //=============================================================================
102 // Function:
103 //    GmmIsUVPacked
104 //
105 // Description:
106 //     Checks if format has packed UV plane
107 //
108 // Arguments: <Look at Function Header)
109 //
110 // Return:
111 //    1 or 0
112 //-----------------------------------------------------------------------------
GmmIsUVPacked(GMM_RESOURCE_FORMAT Format)113 uint8_t GMM_STDCALL GmmIsUVPacked(GMM_RESOURCE_FORMAT Format)
114 {
115     uint8_t Status = 0;
116 
117     switch(Format)
118     {
119         case GMM_FORMAT_NV11:
120         case GMM_FORMAT_NV12:
121         case GMM_FORMAT_NV21:
122         case GMM_FORMAT_P010:
123         case GMM_FORMAT_P012:
124         case GMM_FORMAT_P016:
125         case GMM_FORMAT_P208:
126         case GMM_FORMAT_P216:
127             Status = 1;
128             break;
129         default:
130             Status = 0;
131             break;
132     }
133     return Status;
134 }
135 
136 /////////////////////////////////////////////////////////////////////////////////////
137 /// Checks if format can be accessed by LCU
138 ///
139 /// @param[in]  pSurf: ptr to ::GMM_TEXTURE_INFO of main surface
140 /// @param[in]  pAuxTexInfo: ptr to ::GMM_TEXTURE_INFO of Aux surface
141 ///
142 /////////////////////////////////////////////////////////////////////////////////////
GmmIsYUVFormatLCUAligned(GMM_RESOURCE_FORMAT Format)143 bool GMM_STDCALL GmmIsYUVFormatLCUAligned(GMM_RESOURCE_FORMAT Format)
144 {
145     bool Status = 0;
146 
147     switch(Format)
148     {
149         case GMM_FORMAT_NV12:
150         case GMM_FORMAT_P010:
151         case GMM_FORMAT_P016:
152         case GMM_FORMAT_YUY2:
153         case GMM_FORMAT_Y210:
154         case GMM_FORMAT_Y410:
155         case GMM_FORMAT_Y216:
156         case GMM_FORMAT_Y416:
157         case GMM_FORMAT_AYUV:
158             Status = true;
159             break;
160         default:
161             Status = false;
162             break;
163     }
164     return Status;
165 }
166 
167 //=============================================================================
168 // Function:
169 //    GmmIsYUVPacked
170 //
171 // Description:
172 //     Checks if format is a YCRCB_xxx format supported by the sampler.
173 //
174 // Arguments: <Look at Function Header)
175 //
176 // Return:
177 //    1 or 0
178 //-----------------------------------------------------------------------------
GmmIsYUVPacked(GMM_RESOURCE_FORMAT Format)179 uint8_t GMM_STDCALL GmmIsYUVPacked(GMM_RESOURCE_FORMAT Format)
180 {
181     uint8_t Status = 0;
182 
183     switch(Format)
184     {
185         // YCRCB_xxx Format Supported by the Sampler...
186         case GMM_FORMAT_YUY2:
187         case GMM_FORMAT_YVYU:
188         case GMM_FORMAT_UYVY:
189         case GMM_FORMAT_VYUY:
190         case GMM_FORMAT_YUY2_2x1:
191         case GMM_FORMAT_YVYU_2x1:
192         case GMM_FORMAT_UYVY_2x1:
193         case GMM_FORMAT_VYUY_2x1:
194         case GMM_FORMAT_Y210:
195         case GMM_FORMAT_Y212:
196         case GMM_FORMAT_Y216:
197         case GMM_FORMAT_Y410:
198         case GMM_FORMAT_Y412:
199         case GMM_FORMAT_Y416:
200         case GMM_FORMAT_AYUV:
201             Status = 1;
202             break;
203         default:
204             Status = 0;
205             break;
206     }
207     return Status;
208 }
209 
210 //=============================================================================
211 // Function:
212 //    GmmIsPlanar
213 //
214 // Description:
215 //     Checks if format is YUV planar
216 //
217 // Arguments: <Look at Function Header)
218 //
219 // Return:
220 //    1 or 0
221 //-----------------------------------------------------------------------------
GmmIsPlanar(GMM_RESOURCE_FORMAT Format)222 uint8_t GMM_STDCALL GmmIsPlanar(GMM_RESOURCE_FORMAT Format)
223 {
224     uint8_t Status = 0;
225 
226     switch(Format)
227     {
228         // YUV Planar Formats
229         case GMM_FORMAT_BGRP:
230         case GMM_FORMAT_IMC1:
231         case GMM_FORMAT_IMC2:
232         case GMM_FORMAT_IMC3:
233         case GMM_FORMAT_IMC4:
234         case GMM_FORMAT_I420: //Same as IYUV.
235         case GMM_FORMAT_IYUV:
236         case GMM_FORMAT_MFX_JPEG_YUV411:
237         case GMM_FORMAT_MFX_JPEG_YUV411R:
238         case GMM_FORMAT_MFX_JPEG_YUV420:
239         case GMM_FORMAT_MFX_JPEG_YUV422H:
240         case GMM_FORMAT_MFX_JPEG_YUV422V:
241         case GMM_FORMAT_MFX_JPEG_YUV444:
242         case GMM_FORMAT_RGBP:
243         case GMM_FORMAT_YV12:
244         case GMM_FORMAT_YVU9:
245         // YUV Hybrid Formats - GMM treats as Planar
246         case GMM_FORMAT_NV11:
247         case GMM_FORMAT_NV12:
248         case GMM_FORMAT_NV21:
249         case GMM_FORMAT_P010:
250         case GMM_FORMAT_P012:
251         case GMM_FORMAT_P016:
252         case GMM_FORMAT_P208:
253         case GMM_FORMAT_P216:
254             Status = 1;
255             break;
256         default:
257             Status = 0;
258             break;
259     }
260     return Status;
261 }
262 
263 //=============================================================================
264 // Function:
265 //    GmmIsReconstructableSurface
266 //
267 // Description:
268 //     Checks if format is GmmIsReconstructableSurface
269 //
270 // Arguments: <Look at Function Header)
271 //
272 // Return:
273 //    1 or 0
274 //-----------------------------------------------------------------------------
GmmIsReconstructableSurface(GMM_RESOURCE_FORMAT Format)275 uint8_t GMM_STDCALL GmmIsReconstructableSurface(GMM_RESOURCE_FORMAT Format)
276 {
277     uint8_t Status = 0;
278 
279     switch(Format)
280     {
281         case GMM_FORMAT_AYUV:
282         case GMM_FORMAT_P010:
283         case GMM_FORMAT_P012:
284         case GMM_FORMAT_P016:
285         case GMM_FORMAT_Y210:
286         case GMM_FORMAT_Y216:
287         case GMM_FORMAT_Y212:
288         case GMM_FORMAT_Y410:
289         case GMM_FORMAT_Y416:
290         case GMM_FORMAT_P8:
291         case GMM_FORMAT_NV12:
292         case GMM_FORMAT_YUY2_2x1:
293         case GMM_FORMAT_YUY2:
294             Status = 1;
295             break;
296         default:
297             Status = 0;
298             break;
299     }
300     return Status;
301 }
302 
303 //=============================================================================
304 // Function:
305 //    GmmIsP0xx
306 //
307 // Description:
308 //     Checks if format is P0xx
309 //
310 // Arguments: <Look at Function Header)
311 //
312 // Return:
313 //    1 or 0
314 //-----------------------------------------------------------------------------
GmmIsP0xx(GMM_RESOURCE_FORMAT Format)315 uint8_t GMM_STDCALL GmmIsP0xx(GMM_RESOURCE_FORMAT Format)
316 {
317     uint8_t Status = 0;
318 
319     switch(Format)
320     {
321         case GMM_FORMAT_P010:
322         case GMM_FORMAT_P012:
323         case GMM_FORMAT_P016:
324             Status = 1;
325             break;
326         default:
327             Status = 0;
328             break;
329     }
330 
331     return Status;
332 }
333 
334 //=============================================================================
335 // Function:
336 //    GmmIsCompressed
337 //
338 // Description:
339 //     Checks if format is compressed
340 //
341 // Arguments: <Look at Function Header)
342 //
343 // Return:
344 //    1 or 0
345 //-----------------------------------------------------------------------------
GmmIsCompressed(void * pLibContext,GMM_RESOURCE_FORMAT Format)346 uint8_t GMM_STDCALL GmmIsCompressed(void *pLibContext, GMM_RESOURCE_FORMAT Format)
347 {
348     GMM_LIB_CONTEXT *pGmmLibContext = (GMM_LIB_CONTEXT *)pLibContext;
349 
350     return (Format > GMM_FORMAT_INVALID) &&
351            (Format < GMM_RESOURCE_FORMATS) &&
352            pGmmLibContext->GetPlatformInfo().FormatTable[Format].Compressed;
353 }
354 
355 //=============================================================================
356 // Function:
357 //     GmmGetCacheSizes
358 //
359 // Description:
360 //    This function returns the L3, LLC and EDRAM cache sizes.
361 //
362 // Arguments:
363 //    pCacheSizes ==> ptr to GMM_CACHE_SIZES struct
364 //
365 // Return:
366 //    void
367 //
368 //-----------------------------------------------------------------------------
GmmGetCacheSizes(GMM_LIB_CONTEXT * pGmmLibContext,GMM_CACHE_SIZES * pCacheSizes)369 void GMM_STDCALL GmmGetCacheSizes(GMM_LIB_CONTEXT *pGmmLibContext, GMM_CACHE_SIZES *pCacheSizes)
370 {
371     const GT_SYSTEM_INFO *pGtSysInfo;
372     __GMM_ASSERT(pCacheSizes != NULL);
373     __GMM_ASSERT(pGmmLibContext != NULL);
374 
375     GMM_DPF_ENTER;
376     pGtSysInfo                 = pGmmLibContext->GetGtSysInfoPtr();
377     pCacheSizes->TotalEDRAM    = GMM_KBYTE(pGtSysInfo->EdramSizeInKb);
378     pCacheSizes->TotalLLCCache = GMM_KBYTE(pGtSysInfo->LLCCacheSizeInKb);
379     pCacheSizes->TotalL3Cache  = GMM_KBYTE(pGtSysInfo->L3CacheSizeInKb);
380 
381     GMM_DPF_EXIT;
382 }
383 namespace GmmLib
384 {
385     namespace Utility
386     {
387         //=============================================================================
388         // Function:
389         //    GmmGetNumPlanes
390         //
391         // Description:
392         //     Returns number of planes for given format
393         //
394         // Arguments: <Look at Function Header)
395         //
396         // Return:
397         //    uint32_t number of planes
398         //-----------------------------------------------------------------------------
GmmGetNumPlanes(GMM_RESOURCE_FORMAT Format)399         uint32_t GMM_STDCALL GmmGetNumPlanes(GMM_RESOURCE_FORMAT Format)
400         {
401             uint32_t Planes = 1;
402 
403             switch(Format)
404             {
405                 // YUV Planar Formats
406                 case GMM_FORMAT_BGRP:
407                 case GMM_FORMAT_IMC1:
408                 case GMM_FORMAT_IMC2:
409                 case GMM_FORMAT_IMC3:
410                 case GMM_FORMAT_IMC4:
411                 case GMM_FORMAT_I420:
412                 case GMM_FORMAT_IYUV:
413                 case GMM_FORMAT_MFX_JPEG_YUV411:
414                 case GMM_FORMAT_MFX_JPEG_YUV411R:
415                 case GMM_FORMAT_MFX_JPEG_YUV420:
416                 case GMM_FORMAT_MFX_JPEG_YUV422H:
417                 case GMM_FORMAT_MFX_JPEG_YUV422V:
418                 case GMM_FORMAT_MFX_JPEG_YUV444:
419                 case GMM_FORMAT_RGBP:
420                 case GMM_FORMAT_YV12:
421                 case GMM_FORMAT_YVU9:
422                     Planes = 3;
423                     break;
424                 // YUV Hybrid Formats - GMM treats as Planar
425                 case GMM_FORMAT_NV11:
426                 case GMM_FORMAT_NV12:
427                 case GMM_FORMAT_NV21:
428                 case GMM_FORMAT_P010:
429                 case GMM_FORMAT_P012:
430                 case GMM_FORMAT_P016:
431                 case GMM_FORMAT_P208:
432                 case GMM_FORMAT_P216:
433                     Planes = 2;
434                     break;
435                 default:
436                     Planes = 1;
437                     break;
438             }
439             return Planes;
440         }
441 
442         //==============================================================================
443         //
444         // Function:
445         //      GmmGetFormatForASTC
446         //
447         // Description: See below.
448         //
449         // Returns:
450         //      GMM_RESOURCE_FORMAT for described ASTC format or GMM_FORMAT_INVALID(0)
451         //      if invalid params specified.
452         //
453         //-----------------------------------------------------------------------------
GmmGetFormatForASTC(uint8_t HDR,uint8_t Float,uint32_t BlockWidth,uint32_t BlockHeight,uint32_t BlockDepth)454         GMM_RESOURCE_FORMAT GMM_STDCALL GmmGetFormatForASTC(uint8_t HDR, uint8_t Float, uint32_t BlockWidth, uint32_t BlockHeight, uint32_t BlockDepth)
455         {
456             // Full enums/etc. in case we ever need to typedef them...
457             enum GMM_SURFACESTATE_FORMAT_ASTC_DYNAMIC_RANGE
458             {
459                 GMM_SURFACESTATE_FORMAT_ASTC_DYNAMIC_RANGE_LDR = 0,
460                 GMM_SURFACESTATE_FORMAT_ASTC_DYNAMIC_RANGE_HDR = 1,
461             };
462 
463             enum GMM_SURFACESTATE_FORMAT_ASTC_BLOCK_DIMENSION
464             {
465                 GMM_SURFACESTATE_FORMAT_ASTC_BLOCK_DIMENSION_2D = 0,
466                 GMM_SURFACESTATE_FORMAT_ASTC_BLOCK_DIMENSION_3D = 1,
467             };
468 
469             enum GMM_SURFACESTATE_FORMAT_ASTC_DECODE_FORMAT
470             {
471                 GMM_SURFACESTATE_FORMAT_ASTC_DECODE_FORMAT_UNORM8_sRGB = 0,
472                 GMM_SURFACESTATE_FORMAT_ASTC_DECODE_FORMAT_FLOAT16     = 1,
473             };
474 
475             enum GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE
476             {
477                 GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_4px   = 0,
478                 GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_5px   = 1,
479                 GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_6px   = 2,
480                 __GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_0x3 = 3,
481                 GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_8px   = 4,
482                 __GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_0x5 = 5,
483                 GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_10px  = 6,
484                 GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_12px  = 7,
485             };
486 
487             enum GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE
488             {
489                 GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_3px = 0,
490                 GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_4px = 1,
491                 GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_5px = 2,
492                 GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_6px = 3,
493             };
494 
495             union GMM_SURFACESTATE_FORMAT_ASTC {
496                 struct // Common Fields...
497                 {
498                     uint32_t Reserved1 : 6;      // [2D/3D-Specific Fields]
499                     uint32_t DecodeFormat : 1;   // GMM_SURFACESTATE_FORMAT_ASTC_DECODE_FORMAT
500                     uint32_t BlockDimension : 1; // GMM_SURFACESTATE_FORMAT_ASTC_BLOCK_DIMENSION
501                     uint32_t DynamicRange : 1;   // GMM_SURFACESTATE_FORMAT_ASTC_DYNAMIC_RANGE
502                     uint32_t Reserved2 : 23;
503                 };
504                 struct // 2D-Specific Fields...
505                 {
506                     uint32_t BlockHeight2D : 3; // GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE
507                     uint32_t BlockWidth2D : 3;  // GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE
508                     uint32_t Reserved3 : 3;     // [Common Fields]
509                     uint32_t Reserved4 : 23;
510                 };
511                 struct // 3D-Specific Fields...
512                 {
513                     uint32_t BlockDepth3D : 2;  // GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE
514                     uint32_t BlockHeight3D : 2; // GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE
515                     uint32_t BlockWidth3D : 2;  // GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE
516                     uint32_t Reserved5 : 3;     // [Common Fields]
517                     uint32_t Reserved6 : 23;
518                 };
519                 struct
520                 {
521                     uint32_t Value : 9;
522                     uint32_t Reserved7 : 23;
523                 };
524             } Format = {0};
525             C_ASSERT(sizeof(union GMM_SURFACESTATE_FORMAT_ASTC) == sizeof(uint32_t));
526 
527             // TODO(Minor): Verify and fail for invalid HDR/sRGB combinations.
528 
529             if(BlockDepth == 0)
530                 BlockDepth = 1;
531 
532             Format.DynamicRange = HDR ?
533                                   GMM_SURFACESTATE_FORMAT_ASTC_DYNAMIC_RANGE_HDR :
534                                   GMM_SURFACESTATE_FORMAT_ASTC_DYNAMIC_RANGE_LDR;
535 
536             Format.DecodeFormat = Float ?
537                                   GMM_SURFACESTATE_FORMAT_ASTC_DECODE_FORMAT_FLOAT16 :
538                                   GMM_SURFACESTATE_FORMAT_ASTC_DECODE_FORMAT_UNORM8_sRGB;
539 
540             // Validate Block Dimensions...
541             if(!(
542 #define GMM_FORMAT_INCLUDE_ASTC_FORMATS_ONLY
543 #define GMM_FORMAT(Name, bpe, Width, Height, Depth, IsRT, IsASTC, RcsSurfaceFormat, SSCompressionFmt, Availability) \
544     ((BlockWidth == (Width)) && (BlockHeight == (Height)) && (BlockDepth == (Depth))) ||
545 #include "External/Common/GmmFormatTable.h"
546                0)) // <-- 0 benignly terminates the chain of OR expressions.
547             {
548                 goto Invalid;
549             }
550 
551             if(BlockDepth <= 1)
552             {
553                 Format.BlockDimension = GMM_SURFACESTATE_FORMAT_ASTC_BLOCK_DIMENSION_2D;
554 
555                 // clang-format off
556                 Format.BlockWidth2D =
557                     (BlockWidth ==  4) ? GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_4px :
558                     (BlockWidth ==  5) ? GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_5px :
559                     (BlockWidth ==  6) ? GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_6px :
560                     (BlockWidth ==  8) ? GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_8px :
561                     (BlockWidth == 10) ? GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_10px :
562                     GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_12px;
563                 Format.BlockHeight2D =
564                     (BlockHeight ==  4) ? GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_4px :
565                     (BlockHeight ==  5) ? GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_5px :
566                     (BlockHeight ==  6) ? GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_6px :
567                     (BlockHeight ==  8) ? GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_8px :
568                     (BlockHeight == 10) ? GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_10px :
569                     GMM_SURFACESTATE_FORMAT_ASTC_2D_BLOCK_SIZE_12px;
570                 // clang-format on
571             }
572             else
573             {
574                 Format.BlockDimension = GMM_SURFACESTATE_FORMAT_ASTC_BLOCK_DIMENSION_3D;
575                 // clang-format off
576                 Format.BlockWidth3D =
577                     (BlockWidth == 3) ? GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_3px :
578                     (BlockWidth == 4) ? GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_4px :
579                     (BlockWidth == 5) ? GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_5px :
580                     GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_6px;
581                 Format.BlockHeight3D =
582                     (BlockHeight == 3) ? GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_3px :
583                     (BlockHeight == 4) ? GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_4px :
584                     (BlockHeight == 5) ? GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_5px :
585                     GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_6px;
586                 Format.BlockDepth3D =
587                     (BlockDepth == 3) ? GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_3px :
588                     (BlockDepth == 4) ? GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_4px :
589                     (BlockDepth == 5) ? GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_5px :
590                     GMM_SURFACESTATE_FORMAT_ASTC_3D_BLOCK_SIZE_6px;
591                 // clang-format on
592             }
593 
594             return ((GMM_RESOURCE_FORMAT)Format.Value);
595         Invalid:
596             return (GMM_FORMAT_INVALID);
597         }
598 
599 
600     } // namespace Utility
601 } // namespace GmmLib
602 
603 //=============================================================================
604 //
605 // Function: __GmmLog2
606 //
607 // Desc: Returns Log2 of passed value. Useful for indexing into arrays.
608 //
609 // Parameters:
610 //      Value => Must be power of 2
611 //
612 // Returns:
613 //      See desc.
614 //      Example Value =  8 => Log2(Value) = 3
615 //      Example Value = 32 => Log2(Value) = 5
616 //-----------------------------------------------------------------------------
__GmmLog2(uint32_t Value)617 uint32_t __GmmLog2(uint32_t Value)
618 {
619     uint32_t FirstSetBit = 0; // bit # of first set bit in Bpp.
620 
621 #if _MSC_VER
622     // Check that Value is pow2
623     __GMM_ASSERT(__popcnt(Value) <= 1);
624     _BitScanReverse((DWORD *)&FirstSetBit, (DWORD)Value);
625 #else
626     // Check that Value is pow2
627     __GMM_ASSERT(__builtin_popcount(Value) <= 1);
628     FirstSetBit = __builtin_ctz(Value);
629 #endif
630 
631     // Log2(Value) = FirstSetBit.
632     return FirstSetBit;
633 };
634 
635 // Table for converting the tile layout of DirectX tiled resources
636 // to TileY.
637 const uint32_t __GmmTileYConversionTable[5][2] =
638 {
639 //WxH 256x256, of 64KB tile in texels, BPP = 8
640 {2, 8}, // = (W * (BPP >> 3)) / 128, H / 32
641 //WxH 256x128, BPP = 16
642 {4, 4},
643 //WxH 128x128, BPP = 32
644 {4, 4},
645 //WxH 128x64,  BPP = 64
646 {8, 2},
647 //WxH 64x64,   BPP = 128
648 {8, 2}};
649 
650 // With MSAA, modify DirectX tile dimensions
651 // MSAA  Divide Tile Dimensions (WxH) by
652 // 1          1x1
653 // 2          2x1
654 // 4          2x2
655 // 8          4x2
656 //16          4x4
657 const uint32_t __GmmMSAAConversion[5][2] =
658 {
659 // MSAA 1x
660 {1, 1},
661 // MSAA 2x
662 {2, 1},
663 // MSAA 4x
664 {2, 2},
665 // MSAA 8x
666 {4, 2},
667 // MSAA 16x
668 {4, 4}};
669