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 DEBUG
177 ApplyDebugPrinters(pCreateIn->callbacks.debugPrint, pCreateIn->hClient);
178 #endif
179
180 if ((returnCode == ADDR_OK) &&
181 (pCreateIn->callbacks.allocSysMem != NULL) &&
182 (pCreateIn->callbacks.freeSysMem != NULL))
183 {
184 Client client = {
185 pCreateIn->hClient,
186 pCreateIn->callbacks
187 };
188
189 switch (pCreateIn->chipEngine)
190 {
191 case CIASICIDGFXENGINE_SOUTHERNISLAND:
192 switch (pCreateIn->chipFamily)
193 {
194 case FAMILY_SI:
195 pLib = SiHwlInit(&client);
196 break;
197 case FAMILY_CI:
198 case FAMILY_KV: // CI based fusion
199 case FAMILY_VI:
200 case FAMILY_CZ: // VI based fusion
201 pLib = CiHwlInit(&client);
202 break;
203 default:
204 ADDR_ASSERT_ALWAYS();
205 break;
206 }
207 break;
208 case CIASICIDGFXENGINE_ARCTICISLAND:
209 switch (pCreateIn->chipFamily)
210 {
211 case FAMILY_AI:
212 case FAMILY_RV:
213 pLib = Gfx9HwlInit(&client);
214 break;
215 case FAMILY_NV:
216 case FAMILY_VGH:
217 case FAMILY_RMB:
218 case FAMILY_RPL:
219 case FAMILY_MDN:
220 pLib = Gfx10HwlInit(&client);
221 break;
222 case FAMILY_NV3:
223 case FAMILY_GFX1150:
224 case FAMILY_GFX1103:
225 pLib = Gfx11HwlInit(&client);
226 break;
227 case FAMILY_GFX12:
228 pLib = Gfx12HwlInit(&client);
229 break;
230 default:
231 ADDR_ASSERT_ALWAYS();
232 break;
233 }
234 break;
235 default:
236 ADDR_ASSERT_ALWAYS();
237 break;
238 }
239 }
240
241 if(pLib == NULL)
242 {
243 returnCode = ADDR_OUTOFMEMORY;
244 }
245 if (pLib != NULL)
246 {
247 BOOL_32 initValid;
248
249 // Pass createFlags to configFlags first since these flags may be overwritten
250 pLib->m_configFlags.noCubeMipSlicesPad = pCreateIn->createFlags.noCubeMipSlicesPad;
251 pLib->m_configFlags.fillSizeFields = pCreateIn->createFlags.fillSizeFields;
252 pLib->m_configFlags.useTileIndex = pCreateIn->createFlags.useTileIndex;
253 pLib->m_configFlags.useCombinedSwizzle = pCreateIn->createFlags.useCombinedSwizzle;
254 pLib->m_configFlags.checkLast2DLevel = pCreateIn->createFlags.checkLast2DLevel;
255 pLib->m_configFlags.useHtileSliceAlign = pCreateIn->createFlags.useHtileSliceAlign;
256 pLib->m_configFlags.allowLargeThickTile = pCreateIn->createFlags.allowLargeThickTile;
257 pLib->m_configFlags.forceDccAndTcCompat = pCreateIn->createFlags.forceDccAndTcCompat;
258 pLib->m_configFlags.nonPower2MemConfig = pCreateIn->createFlags.nonPower2MemConfig;
259 pLib->m_configFlags.enableAltTiling = pCreateIn->createFlags.enableAltTiling;
260 pLib->m_configFlags.disableLinearOpt = FALSE;
261
262 pLib->SetChipFamily(pCreateIn->chipFamily, pCreateIn->chipRevision);
263
264 pLib->SetMinPitchAlignPixels(pCreateIn->minPitchAlignPixels);
265
266 // Global parameters initialized and remaining configFlags bits are set as well
267 initValid = pLib->HwlInitGlobalParams(pCreateIn);
268
269 if (initValid)
270 {
271 pLib->m_pElemLib = ElemLib::Create(pLib);
272 }
273 else
274 {
275 pLib->m_pElemLib = NULL; // Don't go on allocating element lib
276 returnCode = ADDR_INVALIDGBREGVALUES;
277 }
278
279 if (pLib->m_pElemLib == NULL)
280 {
281 delete pLib;
282 pLib = NULL;
283 returnCode = ADDR_OUTOFMEMORY;
284 ADDR_ASSERT_ALWAYS();
285 }
286 else
287 {
288 pLib->m_pElemLib->SetConfigFlags(pLib->m_configFlags);
289 }
290 }
291
292 pCreateOut->hLib = pLib;
293
294 if ((pLib != NULL) &&
295 (returnCode == ADDR_OK))
296 {
297 pCreateOut->numEquations =
298 pLib->HwlGetEquationTableInfo(&pCreateOut->pEquationTable);
299
300 pLib->SetMaxAlignments();
301
302 }
303
304 return returnCode;
305 }
306
307 /**
308 ****************************************************************************************************
309 * Lib::SetChipFamily
310 *
311 * @brief
312 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
313 * @return
314 * N/A
315 ****************************************************************************************************
316 */
SetChipFamily(UINT_32 uChipFamily,UINT_32 uChipRevision)317 VOID Lib::SetChipFamily(
318 UINT_32 uChipFamily, ///< [in] chip family defined in atiih.h
319 UINT_32 uChipRevision) ///< [in] chip revision defined in "asic_family"_id.h
320 {
321 ChipFamily family = HwlConvertChipFamily(uChipFamily, uChipRevision);
322
323 ADDR_ASSERT(family != ADDR_CHIP_FAMILY_IVLD);
324
325 m_chipFamily = family;
326 m_chipRevision = uChipRevision;
327 }
328
329 /**
330 ****************************************************************************************************
331 * Lib::SetMinPitchAlignPixels
332 *
333 * @brief
334 * Set m_minPitchAlignPixels with input param
335 *
336 * @return
337 * N/A
338 ****************************************************************************************************
339 */
SetMinPitchAlignPixels(UINT_32 minPitchAlignPixels)340 VOID Lib::SetMinPitchAlignPixels(
341 UINT_32 minPitchAlignPixels) ///< [in] minmum pitch alignment in pixels
342 {
343 m_minPitchAlignPixels = (minPitchAlignPixels == 0) ? 1 : minPitchAlignPixels;
344 }
345
346 /**
347 ****************************************************************************************************
348 * Lib::SetMaxAlignments
349 *
350 * @brief
351 * Set max alignments
352 *
353 * @return
354 * N/A
355 ****************************************************************************************************
356 */
SetMaxAlignments()357 VOID Lib::SetMaxAlignments()
358 {
359 m_maxBaseAlign = HwlComputeMaxBaseAlignments();
360 m_maxMetaBaseAlign = HwlComputeMaxMetaBaseAlignments();
361 }
362
363 /**
364 ****************************************************************************************************
365 * Lib::GetLib
366 *
367 * @brief
368 * Get AddrLib pointer
369 *
370 * @return
371 * An AddrLib class pointer
372 ****************************************************************************************************
373 */
GetLib(ADDR_HANDLE hLib)374 Lib* Lib::GetLib(
375 ADDR_HANDLE hLib) ///< [in] handle of ADDR_HANDLE
376 {
377 Lib* pLib = static_cast<Addr::Lib*>(hLib);
378 #if DEBUG
379 if (pLib != NULL)
380 {
381 pLib->SetDebugPrinters();
382 }
383 #endif
384 return pLib;
385 }
386
387 /**
388 ****************************************************************************************************
389 * Lib::GetMaxAlignments
390 *
391 * @brief
392 * Gets maximum alignments for data surface (include FMask)
393 *
394 * @return
395 * ADDR_E_RETURNCODE
396 ****************************************************************************************************
397 */
GetMaxAlignments(ADDR_GET_MAX_ALIGNMENTS_OUTPUT * pOut) const398 ADDR_E_RETURNCODE Lib::GetMaxAlignments(
399 ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut ///< [out] output structure
400 ) const
401 {
402 ADDR_E_RETURNCODE returnCode = ADDR_OK;
403
404 if (GetFillSizeFieldsFlags() == TRUE)
405 {
406 if (pOut->size != sizeof(ADDR_GET_MAX_ALIGNMENTS_OUTPUT))
407 {
408 returnCode = ADDR_PARAMSIZEMISMATCH;
409 }
410 }
411
412 if (returnCode == ADDR_OK)
413 {
414 if (m_maxBaseAlign != 0)
415 {
416 pOut->baseAlign = m_maxBaseAlign;
417 }
418 else
419 {
420 returnCode = ADDR_NOTIMPLEMENTED;
421 }
422 }
423
424 return returnCode;
425 }
426
427 /**
428 ****************************************************************************************************
429 * Lib::GetMaxMetaAlignments
430 *
431 * @brief
432 * Gets maximum alignments for metadata (CMask, DCC and HTile)
433 *
434 * @return
435 * ADDR_E_RETURNCODE
436 ****************************************************************************************************
437 */
GetMaxMetaAlignments(ADDR_GET_MAX_ALIGNMENTS_OUTPUT * pOut) const438 ADDR_E_RETURNCODE Lib::GetMaxMetaAlignments(
439 ADDR_GET_MAX_ALIGNMENTS_OUTPUT* pOut ///< [out] output structure
440 ) const
441 {
442 ADDR_E_RETURNCODE returnCode = ADDR_OK;
443
444 if (GetFillSizeFieldsFlags() == TRUE)
445 {
446 if (pOut->size != sizeof(ADDR_GET_MAX_ALIGNMENTS_OUTPUT))
447 {
448 returnCode = ADDR_PARAMSIZEMISMATCH;
449 }
450 }
451
452 if (returnCode == ADDR_OK)
453 {
454 if (m_maxMetaBaseAlign != 0)
455 {
456 pOut->baseAlign = m_maxMetaBaseAlign;
457 }
458 else
459 {
460 returnCode = ADDR_NOTIMPLEMENTED;
461 }
462 }
463
464 return returnCode;
465 }
466
467 /**
468 ****************************************************************************************************
469 * Lib::Bits2Number
470 *
471 * @brief
472 * Cat a array of binary bit to a number
473 *
474 * @return
475 * The number combined with the array of bits
476 ****************************************************************************************************
477 */
Bits2Number(UINT_32 bitNum,...)478 UINT_32 Lib::Bits2Number(
479 UINT_32 bitNum, ///< [in] how many bits
480 ...) ///< [in] varaible bits value starting from MSB
481 {
482 UINT_32 number = 0;
483 UINT_32 i;
484 va_list bits_ptr;
485
486 va_start(bits_ptr, bitNum);
487
488 for(i = 0; i < bitNum; i++)
489 {
490 number |= va_arg(bits_ptr, UINT_32);
491 number <<= 1;
492 }
493
494 number >>= 1;
495
496 va_end(bits_ptr);
497
498 return number;
499 }
500
501
502 ////////////////////////////////////////////////////////////////////////////////////////////////////
503 // Element lib
504 ////////////////////////////////////////////////////////////////////////////////////////////////////
505
506
507 /**
508 ****************************************************************************************************
509 * Lib::Flt32ToColorPixel
510 *
511 * @brief
512 * Convert a FLT_32 value to a depth/stencil pixel value
513 * @return
514 * ADDR_E_RETURNCODE
515 ****************************************************************************************************
516 */
Flt32ToDepthPixel(const ELEM_FLT32TODEPTHPIXEL_INPUT * pIn,ELEM_FLT32TODEPTHPIXEL_OUTPUT * pOut) const517 ADDR_E_RETURNCODE Lib::Flt32ToDepthPixel(
518 const ELEM_FLT32TODEPTHPIXEL_INPUT* pIn,
519 ELEM_FLT32TODEPTHPIXEL_OUTPUT* pOut) const
520 {
521 ADDR_E_RETURNCODE returnCode = ADDR_OK;
522
523 if (GetFillSizeFieldsFlags() == TRUE)
524 {
525 if ((pIn->size != sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT)) ||
526 (pOut->size != sizeof(ELEM_FLT32TODEPTHPIXEL_OUTPUT)))
527 {
528 returnCode = ADDR_PARAMSIZEMISMATCH;
529 }
530 }
531
532 if (returnCode == ADDR_OK)
533 {
534 GetElemLib()->Flt32ToDepthPixel(pIn->format, pIn->comps, pOut->pPixel);
535
536 UINT_32 depthBase = 0;
537 UINT_32 stencilBase = 0;
538 UINT_32 depthBits = 0;
539 UINT_32 stencilBits = 0;
540
541 switch (pIn->format)
542 {
543 case ADDR_DEPTH_16:
544 depthBits = 16;
545 break;
546 case ADDR_DEPTH_X8_24:
547 case ADDR_DEPTH_8_24:
548 case ADDR_DEPTH_X8_24_FLOAT:
549 case ADDR_DEPTH_8_24_FLOAT:
550 depthBase = 8;
551 depthBits = 24;
552 stencilBits = 8;
553 break;
554 case ADDR_DEPTH_32_FLOAT:
555 depthBits = 32;
556 break;
557 case ADDR_DEPTH_X24_8_32_FLOAT:
558 depthBase = 8;
559 depthBits = 32;
560 stencilBits = 8;
561 break;
562 default:
563 break;
564 }
565
566 // Overwrite base since R800 has no "tileBase"
567 if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE)
568 {
569 depthBase = 0;
570 stencilBase = 0;
571 }
572
573 depthBase *= 64;
574 stencilBase *= 64;
575
576 pOut->stencilBase = stencilBase;
577 pOut->depthBase = depthBase;
578 pOut->depthBits = depthBits;
579 pOut->stencilBits = stencilBits;
580 }
581
582 return returnCode;
583 }
584
585 /**
586 ****************************************************************************************************
587 * Lib::Flt32ToColorPixel
588 *
589 * @brief
590 * Convert a FLT_32 value to a red/green/blue/alpha pixel value
591 * @return
592 * ADDR_E_RETURNCODE
593 ****************************************************************************************************
594 */
Flt32ToColorPixel(const ELEM_FLT32TOCOLORPIXEL_INPUT * pIn,ELEM_FLT32TOCOLORPIXEL_OUTPUT * pOut) const595 ADDR_E_RETURNCODE Lib::Flt32ToColorPixel(
596 const ELEM_FLT32TOCOLORPIXEL_INPUT* pIn,
597 ELEM_FLT32TOCOLORPIXEL_OUTPUT* pOut) const
598 {
599 ADDR_E_RETURNCODE returnCode = ADDR_OK;
600
601 if (GetFillSizeFieldsFlags() == TRUE)
602 {
603 if ((pIn->size != sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT)) ||
604 (pOut->size != sizeof(ELEM_FLT32TOCOLORPIXEL_OUTPUT)))
605 {
606 returnCode = ADDR_PARAMSIZEMISMATCH;
607 }
608 }
609
610 if (returnCode == ADDR_OK)
611 {
612 GetElemLib()->Flt32ToColorPixel(pIn->format,
613 pIn->surfNum,
614 pIn->surfSwap,
615 pIn->comps,
616 pOut->pPixel);
617 }
618
619 return returnCode;
620 }
621
622
623 /**
624 ****************************************************************************************************
625 * Lib::GetExportNorm
626 *
627 * @brief
628 * Check one format can be EXPORT_NUM
629 * @return
630 * TRUE if EXPORT_NORM can be used
631 ****************************************************************************************************
632 */
GetExportNorm(const ELEM_GETEXPORTNORM_INPUT * pIn) const633 BOOL_32 Lib::GetExportNorm(
634 const ELEM_GETEXPORTNORM_INPUT* pIn) const
635 {
636 ADDR_E_RETURNCODE returnCode = ADDR_OK;
637
638 BOOL_32 enabled = FALSE;
639
640 if (GetFillSizeFieldsFlags() == TRUE)
641 {
642 if (pIn->size != sizeof(ELEM_GETEXPORTNORM_INPUT))
643 {
644 returnCode = ADDR_PARAMSIZEMISMATCH;
645 }
646 }
647
648 if (returnCode == ADDR_OK)
649 {
650 enabled = GetElemLib()->PixGetExportNorm(pIn->format, pIn->num, pIn->swap);
651 }
652
653 return enabled;
654 }
655
656 /**
657 ****************************************************************************************************
658 * Lib::GetBpe
659 *
660 * @brief
661 * Get bits-per-element for specified format
662 * @return
663 * bits-per-element of specified format
664 ****************************************************************************************************
665 */
GetBpe(AddrFormat format) const666 UINT_32 Lib::GetBpe(AddrFormat format) const
667 {
668 return GetElemLib()->GetBitsPerPixel(format);
669 }
670
671 } // Addr
672