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