• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ************************************************************************************************************************
3 *
4 *  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.
5 *  SPDX-License-Identifier: MIT
6 *
7 ***********************************************************************************************************************/
8 
9 /**
10 ****************************************************************************************************
11 * @file  addrlib.cpp
12 * @brief Contains the implementation for the Addr::Lib class.
13 ****************************************************************************************************
14 */
15 
16 #include "addrinterface.h"
17 #include "addrlib.h"
18 #include "addrcommon.h"
19 
20 #if defined(__APPLE__)
21 
div64_32(UINT_64 n,UINT_32 base)22 UINT_32 div64_32(UINT_64 n, UINT_32 base)
23 {
24     UINT_64 rem = n;
25     UINT_64 b = base;
26     UINT_64 res, d = 1;
27     UINT_32 high = rem >> 32;
28 
29     res = 0;
30     if (high >= base)
31     {
32         high /= base;
33         res = (UINT_64) high << 32;
34         rem -= (UINT_64) (high * base) << 32;
35     }
36 
37     while (((INT_64)b > 0) && (b < rem))
38     {
39         b = b + b;
40         d = d + d;
41     }
42 
43     do
44     {
45         if (rem >= b)
46         {
47             rem -= b;
48             res += d;
49         }
50         b >>= 1;
51         d >>= 1;
52     } while (d);
53 
54     n = res;
55     return rem;
56 }
57 
58 extern "C"
__umoddi3(UINT_64 n,UINT_32 base)59 UINT_32 __umoddi3(UINT_64 n, UINT_32 base)
60 {
61     return div64_32(n, base);
62 }
63 
64 #endif // __APPLE__
65 
66 namespace Addr
67 {
68 
69 ////////////////////////////////////////////////////////////////////////////////////////////////////
70 //                               Constructor/Destructor
71 ////////////////////////////////////////////////////////////////////////////////////////////////////
72 
73 /**
74 ****************************************************************************************************
75 *   Lib::Lib
76 *
77 *   @brief
78 *       Constructor for the AddrLib class
79 *
80 ****************************************************************************************************
81 */
Lib()82 Lib::Lib() :
83     m_chipFamily(ADDR_CHIP_FAMILY_IVLD),
84     m_chipRevision(0),
85     m_version(ADDRLIB_VERSION),
86     m_pipes(0),
87     m_banks(0),
88     m_pipeInterleaveBytes(0),
89     m_rowSize(0),
90     m_minPitchAlignPixels(1),
91     m_maxSamples(8),
92     m_maxBaseAlign(0),
93     m_maxMetaBaseAlign(0),
94     m_pElemLib(NULL)
95 {
96     m_configFlags.value = 0;
97 }
98 
99 /**
100 ****************************************************************************************************
101 *   Lib::Lib
102 *
103 *   @brief
104 *       Constructor for the AddrLib class with hClient as parameter
105 *
106 ****************************************************************************************************
107 */
Lib(const Client * pClient)108 Lib::Lib(const Client* pClient) :
109     Object(pClient),
110     m_chipFamily(ADDR_CHIP_FAMILY_IVLD),
111     m_chipRevision(0),
112     m_version(ADDRLIB_VERSION),
113     m_pipes(0),
114     m_banks(0),
115     m_pipeInterleaveBytes(0),
116     m_rowSize(0),
117     m_minPitchAlignPixels(1),
118     m_maxSamples(8),
119     m_maxBaseAlign(0),
120     m_maxMetaBaseAlign(0),
121     m_pElemLib(NULL)
122 {
123     m_configFlags.value = 0;
124 }
125 
126 /**
127 ****************************************************************************************************
128 *   Lib::~AddrLib
129 *
130 *   @brief
131 *       Destructor for the AddrLib class
132 *
133 ****************************************************************************************************
134 */
~Lib()135 Lib::~Lib()
136 {
137     if (m_pElemLib)
138     {
139         delete m_pElemLib;
140         m_pElemLib = NULL;
141     }
142 }
143 
144 
145 ////////////////////////////////////////////////////////////////////////////////////////////////////
146 //                               Initialization/Helper
147 ////////////////////////////////////////////////////////////////////////////////////////////////////
148 
149 /**
150 ****************************************************************************************************
151 *   Lib::Create
152 *
153 *   @brief
154 *       Creates and initializes AddrLib object.
155 *
156 *   @return
157 *       ADDR_E_RETURNCODE
158 ****************************************************************************************************
159 */
Create(const ADDR_CREATE_INPUT * pCreateIn,ADDR_CREATE_OUTPUT * pCreateOut)160 ADDR_E_RETURNCODE Lib::Create(
161     const ADDR_CREATE_INPUT* pCreateIn,     ///< [in] pointer to ADDR_CREATE_INPUT
162     ADDR_CREATE_OUTPUT*      pCreateOut)    ///< [out] pointer to ADDR_CREATE_OUTPUT
163 {
164     Lib* pLib = NULL;
165     ADDR_E_RETURNCODE returnCode = ADDR_OK;
166 
167     if (pCreateIn->createFlags.fillSizeFields == TRUE)
168     {
169         if ((pCreateIn->size != sizeof(ADDR_CREATE_INPUT)) ||
170             (pCreateOut->size != sizeof(ADDR_CREATE_OUTPUT)))
171         {
172             returnCode = ADDR_PARAMSIZEMISMATCH;
173         }
174     }
175 
176     if ((returnCode == ADDR_OK)                    &&
177         (pCreateIn->callbacks.allocSysMem != NULL) &&
178         (pCreateIn->callbacks.freeSysMem != NULL))
179     {
180         Client client = {
181             pCreateIn->hClient,
182             pCreateIn->callbacks
183         };
184 
185         switch (pCreateIn->chipEngine)
186         {
187             case CIASICIDGFXENGINE_SOUTHERNISLAND:
188                 switch (pCreateIn->chipFamily)
189                 {
190                     case FAMILY_SI:
191                         pLib = SiHwlInit(&client);
192                         break;
193                     case FAMILY_VI:
194                     case FAMILY_CZ: // VI based fusion
195                     case FAMILY_CI:
196                     case FAMILY_KV: // CI based fusion
197                         pLib = CiHwlInit(&client);
198                         break;
199                     default:
200                         ADDR_ASSERT_ALWAYS();
201                         break;
202                 }
203                 break;
204             case CIASICIDGFXENGINE_ARCTICISLAND:
205                 switch (pCreateIn->chipFamily)
206                 {
207                     case FAMILY_AI:
208                     case FAMILY_RV:
209                         pLib = Gfx9HwlInit(&client);
210                         break;
211                     case FAMILY_NV:
212                     case FAMILY_VGH:
213                     case FAMILY_RMB:
214                     case FAMILY_RPL:
215                     case FAMILY_MDN:
216                         pLib = Gfx10HwlInit(&client);
217                         break;
218                     case FAMILY_NV3:
219                     case FAMILY_GFX1103:
220                     case FAMILY_GFX1150:
221                         pLib = Gfx11HwlInit(&client);
222                         break;
223                     default:
224                         ADDR_ASSERT_ALWAYS();
225                         break;
226                 }
227                 break;
228             default:
229                 ADDR_ASSERT_ALWAYS();
230                 break;
231         }
232     }
233 
234     if (pLib != NULL)
235     {
236         BOOL_32 initValid;
237 
238         // Pass createFlags to configFlags first since these flags may be overwritten
239         pLib->m_configFlags.noCubeMipSlicesPad  = pCreateIn->createFlags.noCubeMipSlicesPad;
240         pLib->m_configFlags.fillSizeFields      = pCreateIn->createFlags.fillSizeFields;
241         pLib->m_configFlags.useTileIndex        = pCreateIn->createFlags.useTileIndex;
242         pLib->m_configFlags.useCombinedSwizzle  = pCreateIn->createFlags.useCombinedSwizzle;
243         pLib->m_configFlags.checkLast2DLevel    = pCreateIn->createFlags.checkLast2DLevel;
244         pLib->m_configFlags.useHtileSliceAlign  = pCreateIn->createFlags.useHtileSliceAlign;
245         pLib->m_configFlags.allowLargeThickTile = pCreateIn->createFlags.allowLargeThickTile;
246         pLib->m_configFlags.forceDccAndTcCompat = pCreateIn->createFlags.forceDccAndTcCompat;
247         pLib->m_configFlags.nonPower2MemConfig  = pCreateIn->createFlags.nonPower2MemConfig;
248         pLib->m_configFlags.enableAltTiling     = pCreateIn->createFlags.enableAltTiling;
249         pLib->m_configFlags.disableLinearOpt    = FALSE;
250 
251         pLib->SetChipFamily(pCreateIn->chipFamily, pCreateIn->chipRevision);
252 
253         pLib->SetMinPitchAlignPixels(pCreateIn->minPitchAlignPixels);
254 
255         // Global parameters initialized and remaining configFlags bits are set as well
256         initValid = pLib->HwlInitGlobalParams(pCreateIn);
257 
258         if (initValid)
259         {
260             pLib->m_pElemLib = ElemLib::Create(pLib);
261         }
262         else
263         {
264             pLib->m_pElemLib = NULL; // Don't go on allocating element lib
265             returnCode = ADDR_INVALIDGBREGVALUES;
266         }
267 
268         if (pLib->m_pElemLib == NULL)
269         {
270             delete pLib;
271             pLib = NULL;
272             ADDR_ASSERT_ALWAYS();
273         }
274         else
275         {
276             pLib->m_pElemLib->SetConfigFlags(pLib->m_configFlags);
277         }
278     }
279 
280     pCreateOut->hLib = pLib;
281 
282     if ((pLib != NULL) &&
283         (returnCode == ADDR_OK))
284     {
285         pCreateOut->numEquations =
286             pLib->HwlGetEquationTableInfo(&pCreateOut->pEquationTable);
287 
288         pLib->SetMaxAlignments();
289 
290     }
291     else if ((pLib == NULL) &&
292              (returnCode == ADDR_OK))
293     {
294         // Unknown failures, we return the general error code
295         returnCode = ADDR_ERROR;
296     }
297 
298     return returnCode;
299 }
300 
301 /**
302 ****************************************************************************************************
303 *   Lib::SetChipFamily
304 *
305 *   @brief
306 *       Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
307 *   @return
308 *      N/A
309 ****************************************************************************************************
310 */
SetChipFamily(UINT_32 uChipFamily,UINT_32 uChipRevision)311 VOID Lib::SetChipFamily(
312     UINT_32 uChipFamily,        ///< [in] chip family defined in atiih.h
313     UINT_32 uChipRevision)      ///< [in] chip revision defined in "asic_family"_id.h
314 {
315     ChipFamily family = HwlConvertChipFamily(uChipFamily, uChipRevision);
316 
317     ADDR_ASSERT(family != ADDR_CHIP_FAMILY_IVLD);
318 
319     m_chipFamily   = family;
320     m_chipRevision = uChipRevision;
321 }
322 
323 /**
324 ****************************************************************************************************
325 *   Lib::SetMinPitchAlignPixels
326 *
327 *   @brief
328 *       Set m_minPitchAlignPixels with input param
329 *
330 *   @return
331 *      N/A
332 ****************************************************************************************************
333 */
SetMinPitchAlignPixels(UINT_32 minPitchAlignPixels)334 VOID Lib::SetMinPitchAlignPixels(
335     UINT_32 minPitchAlignPixels)    ///< [in] minmum pitch alignment in pixels
336 {
337     m_minPitchAlignPixels = (minPitchAlignPixels == 0) ? 1 : minPitchAlignPixels;
338 }
339 
340 /**
341 ****************************************************************************************************
342 *   Lib::SetMaxAlignments
343 *
344 *   @brief
345 *       Set max alignments
346 *
347 *   @return
348 *      N/A
349 ****************************************************************************************************
350 */
SetMaxAlignments()351 VOID Lib::SetMaxAlignments()
352 {
353     m_maxBaseAlign     = HwlComputeMaxBaseAlignments();
354     m_maxMetaBaseAlign = HwlComputeMaxMetaBaseAlignments();
355 }
356 
357 /**
358 ****************************************************************************************************
359 *   Lib::GetLib
360 *
361 *   @brief
362 *       Get AddrLib pointer
363 *
364 *   @return
365 *      An AddrLib class pointer
366 ****************************************************************************************************
367 */
GetLib(ADDR_HANDLE hLib)368 Lib* Lib::GetLib(
369     ADDR_HANDLE hLib)   ///< [in] handle of ADDR_HANDLE
370 {
371     return static_cast<Addr::Lib*>(hLib);
372 }
373 
374 /**
375 ****************************************************************************************************
376 *   Lib::GetMaxAlignments
377 *
378 *   @brief
379 *       Gets maximum alignments for data surface (include FMask)
380 *
381 *   @return
382 *       ADDR_E_RETURNCODE
383 ****************************************************************************************************
384 */
GetMaxAlignments(ADDR_GET_MAX_ALIGNMENTS_OUTPUT * pOut) const385 ADDR_E_RETURNCODE Lib::GetMaxAlignments(
386     ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut    ///< [out] output structure
387     ) const
388 {
389     ADDR_E_RETURNCODE returnCode = ADDR_OK;
390 
391     if (GetFillSizeFieldsFlags() == TRUE)
392     {
393         if (pOut->size != sizeof(ADDR_GET_MAX_ALIGNMENTS_OUTPUT))
394         {
395             returnCode = ADDR_PARAMSIZEMISMATCH;
396         }
397     }
398 
399     if (returnCode == ADDR_OK)
400     {
401         if (m_maxBaseAlign != 0)
402         {
403             pOut->baseAlign = m_maxBaseAlign;
404         }
405         else
406         {
407             returnCode = ADDR_NOTIMPLEMENTED;
408         }
409     }
410 
411     return returnCode;
412 }
413 
414 /**
415 ****************************************************************************************************
416 *   Lib::GetMaxMetaAlignments
417 *
418 *   @brief
419 *       Gets maximum alignments for metadata (CMask, DCC and HTile)
420 *
421 *   @return
422 *       ADDR_E_RETURNCODE
423 ****************************************************************************************************
424 */
GetMaxMetaAlignments(ADDR_GET_MAX_ALIGNMENTS_OUTPUT * pOut) const425 ADDR_E_RETURNCODE Lib::GetMaxMetaAlignments(
426     ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut    ///< [out] output structure
427     ) const
428 {
429     ADDR_E_RETURNCODE returnCode = ADDR_OK;
430 
431     if (GetFillSizeFieldsFlags() == TRUE)
432     {
433         if (pOut->size != sizeof(ADDR_GET_MAX_ALIGNMENTS_OUTPUT))
434         {
435             returnCode = ADDR_PARAMSIZEMISMATCH;
436         }
437     }
438 
439     if (returnCode == ADDR_OK)
440     {
441         if (m_maxMetaBaseAlign != 0)
442         {
443             pOut->baseAlign = m_maxMetaBaseAlign;
444         }
445         else
446         {
447             returnCode = ADDR_NOTIMPLEMENTED;
448         }
449     }
450 
451     return returnCode;
452 }
453 
454 /**
455 ****************************************************************************************************
456 *   Lib::Bits2Number
457 *
458 *   @brief
459 *       Cat a array of binary bit to a number
460 *
461 *   @return
462 *       The number combined with the array of bits
463 ****************************************************************************************************
464 */
Bits2Number(UINT_32 bitNum,...)465 UINT_32 Lib::Bits2Number(
466     UINT_32 bitNum,     ///< [in] how many bits
467     ...)                ///< [in] varaible bits value starting from MSB
468 {
469     UINT_32 number = 0;
470     UINT_32 i;
471     va_list bits_ptr;
472 
473     va_start(bits_ptr, bitNum);
474 
475     for(i = 0; i < bitNum; i++)
476     {
477         number |= va_arg(bits_ptr, UINT_32);
478         number <<= 1;
479     }
480 
481     number >>= 1;
482 
483     va_end(bits_ptr);
484 
485     return number;
486 }
487 
488 
489 ////////////////////////////////////////////////////////////////////////////////////////////////////
490 //                               Element lib
491 ////////////////////////////////////////////////////////////////////////////////////////////////////
492 
493 
494 /**
495 ****************************************************************************************************
496 *   Lib::Flt32ToColorPixel
497 *
498 *   @brief
499 *       Convert a FLT_32 value to a depth/stencil pixel value
500 *   @return
501 *       ADDR_E_RETURNCODE
502 ****************************************************************************************************
503 */
Flt32ToDepthPixel(const ELEM_FLT32TODEPTHPIXEL_INPUT * pIn,ELEM_FLT32TODEPTHPIXEL_OUTPUT * pOut) const504 ADDR_E_RETURNCODE Lib::Flt32ToDepthPixel(
505     const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,
506     ELEM_FLT32TODEPTHPIXEL_OUTPUT* pOut) const
507 {
508     ADDR_E_RETURNCODE returnCode = ADDR_OK;
509 
510     if (GetFillSizeFieldsFlags() == TRUE)
511     {
512         if ((pIn->size != sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT)) ||
513             (pOut->size != sizeof(ELEM_FLT32TODEPTHPIXEL_OUTPUT)))
514         {
515             returnCode = ADDR_PARAMSIZEMISMATCH;
516         }
517     }
518 
519     if (returnCode == ADDR_OK)
520     {
521         GetElemLib()->Flt32ToDepthPixel(pIn->format, pIn->comps, pOut->pPixel);
522 
523         UINT_32 depthBase = 0;
524         UINT_32 stencilBase = 0;
525         UINT_32 depthBits = 0;
526         UINT_32 stencilBits = 0;
527 
528         switch (pIn->format)
529         {
530             case ADDR_DEPTH_16:
531                 depthBits = 16;
532                 break;
533             case ADDR_DEPTH_X8_24:
534             case ADDR_DEPTH_8_24:
535             case ADDR_DEPTH_X8_24_FLOAT:
536             case ADDR_DEPTH_8_24_FLOAT:
537                 depthBase = 8;
538                 depthBits = 24;
539                 stencilBits = 8;
540                 break;
541             case ADDR_DEPTH_32_FLOAT:
542                 depthBits = 32;
543                 break;
544             case ADDR_DEPTH_X24_8_32_FLOAT:
545                 depthBase = 8;
546                 depthBits = 32;
547                 stencilBits = 8;
548                 break;
549             default:
550                 break;
551         }
552 
553         // Overwrite base since R800 has no "tileBase"
554         if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE)
555         {
556             depthBase = 0;
557             stencilBase = 0;
558         }
559 
560         depthBase *= 64;
561         stencilBase *= 64;
562 
563         pOut->stencilBase = stencilBase;
564         pOut->depthBase = depthBase;
565         pOut->depthBits = depthBits;
566         pOut->stencilBits = stencilBits;
567     }
568 
569     return returnCode;
570 }
571 
572 /**
573 ****************************************************************************************************
574 *   Lib::Flt32ToColorPixel
575 *
576 *   @brief
577 *       Convert a FLT_32 value to a red/green/blue/alpha pixel value
578 *   @return
579 *       ADDR_E_RETURNCODE
580 ****************************************************************************************************
581 */
Flt32ToColorPixel(const ELEM_FLT32TOCOLORPIXEL_INPUT * pIn,ELEM_FLT32TOCOLORPIXEL_OUTPUT * pOut) const582 ADDR_E_RETURNCODE Lib::Flt32ToColorPixel(
583     const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,
584     ELEM_FLT32TOCOLORPIXEL_OUTPUT* pOut) const
585 {
586     ADDR_E_RETURNCODE returnCode = ADDR_OK;
587 
588     if (GetFillSizeFieldsFlags() == TRUE)
589     {
590         if ((pIn->size != sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT)) ||
591             (pOut->size != sizeof(ELEM_FLT32TOCOLORPIXEL_OUTPUT)))
592         {
593             returnCode = ADDR_PARAMSIZEMISMATCH;
594         }
595     }
596 
597     if (returnCode == ADDR_OK)
598     {
599         GetElemLib()->Flt32ToColorPixel(pIn->format,
600                                         pIn->surfNum,
601                                         pIn->surfSwap,
602                                         pIn->comps,
603                                         pOut->pPixel);
604     }
605 
606     return returnCode;
607 }
608 
609 
610 /**
611 ****************************************************************************************************
612 *   Lib::GetExportNorm
613 *
614 *   @brief
615 *       Check one format can be EXPORT_NUM
616 *   @return
617 *       TRUE if EXPORT_NORM can be used
618 ****************************************************************************************************
619 */
GetExportNorm(const ELEM_GETEXPORTNORM_INPUT * pIn) const620 BOOL_32 Lib::GetExportNorm(
621     const ELEM_GETEXPORTNORM_INPUT* pIn) const
622 {
623     ADDR_E_RETURNCODE returnCode = ADDR_OK;
624 
625     BOOL_32 enabled = FALSE;
626 
627     if (GetFillSizeFieldsFlags() == TRUE)
628     {
629         if (pIn->size != sizeof(ELEM_GETEXPORTNORM_INPUT))
630         {
631             returnCode = ADDR_PARAMSIZEMISMATCH;
632         }
633     }
634 
635     if (returnCode == ADDR_OK)
636     {
637         enabled = GetElemLib()->PixGetExportNorm(pIn->format, pIn->num, pIn->swap);
638     }
639 
640     return enabled;
641 }
642 
643 /**
644 ****************************************************************************************************
645 *   Lib::GetBpe
646 *
647 *   @brief
648 *       Get bits-per-element for specified format
649 *   @return
650 *       bits-per-element of specified format
651 ****************************************************************************************************
652 */
GetBpe(AddrFormat format) const653 UINT_32 Lib::GetBpe(AddrFormat format) const
654 {
655     return GetElemLib()->GetBitsPerPixel(format);
656 }
657 
658 } // Addr
659