2 * Copyright © 2007-2019 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 ****************************************************************************************************
30 * @brief Contains the implementation for the Addr::Lib class.
31 ****************************************************************************************************
34 #include "addrinterface.h"
36 #include "addrcommon.h"
38 #if defined(__APPLE__)
40 UINT_32
div64_32(UINT_64 n
, UINT_32 base
)
45 UINT_32 high
= rem
>> 32;
51 res
= (UINT_64
) high
<< 32;
52 rem
-= (UINT_64
) (high
* base
) << 32;
55 while (((INT_64
)b
> 0) && (b
< rem
))
77 UINT_32
__umoddi3(UINT_64 n
, UINT_32 base
)
79 return div64_32(n
, base
);
87 ////////////////////////////////////////////////////////////////////////////////////////////////////
88 // Constructor/Destructor
89 ////////////////////////////////////////////////////////////////////////////////////////////////////
92 ****************************************************************************************************
96 * Constructor for the AddrLib class
98 ****************************************************************************************************
101 m_class(BASE_ADDRLIB
),
102 m_chipFamily(ADDR_CHIP_FAMILY_IVLD
),
104 m_version(ADDRLIB_VERSION
),
107 m_pipeInterleaveBytes(0),
109 m_minPitchAlignPixels(1),
113 m_configFlags
.value
= 0;
117 ****************************************************************************************************
121 * Constructor for the AddrLib class with hClient as parameter
123 ****************************************************************************************************
125 Lib::Lib(const Client
* pClient
) :
127 m_class(BASE_ADDRLIB
),
128 m_chipFamily(ADDR_CHIP_FAMILY_IVLD
),
130 m_version(ADDRLIB_VERSION
),
133 m_pipeInterleaveBytes(0),
135 m_minPitchAlignPixels(1),
139 m_configFlags
.value
= 0;
143 ****************************************************************************************************
147 * Destructor for the AddrLib class
149 ****************************************************************************************************
160 ////////////////////////////////////////////////////////////////////////////////////////////////////
161 // Initialization/Helper
162 ////////////////////////////////////////////////////////////////////////////////////////////////////
165 ****************************************************************************************************
169 * Creates and initializes AddrLib object.
173 ****************************************************************************************************
175 ADDR_E_RETURNCODE
Lib::Create(
176 const ADDR_CREATE_INPUT
* pCreateIn
, ///< [in] pointer to ADDR_CREATE_INPUT
177 ADDR_CREATE_OUTPUT
* pCreateOut
) ///< [out] pointer to ADDR_CREATE_OUTPUT
180 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
182 if (pCreateIn
->createFlags
.fillSizeFields
== TRUE
)
184 if ((pCreateIn
->size
!= sizeof(ADDR_CREATE_INPUT
)) ||
185 (pCreateOut
->size
!= sizeof(ADDR_CREATE_OUTPUT
)))
187 returnCode
= ADDR_PARAMSIZEMISMATCH
;
191 if ((returnCode
== ADDR_OK
) &&
192 (pCreateIn
->callbacks
.allocSysMem
!= NULL
) &&
193 (pCreateIn
->callbacks
.freeSysMem
!= NULL
))
200 switch (pCreateIn
->chipEngine
)
202 case CIASICIDGFXENGINE_SOUTHERNISLAND
:
203 switch (pCreateIn
->chipFamily
)
206 pLib
= SiHwlInit(&client
);
211 case FAMILY_KV
: // CI based fusion
212 pLib
= CiHwlInit(&client
);
215 ADDR_ASSERT_ALWAYS();
219 case CIASICIDGFXENGINE_ARCTICISLAND
:
220 switch (pCreateIn
->chipFamily
)
224 pLib
= Gfx9HwlInit(&client
);
227 pLib
= Gfx10HwlInit(&client
);
230 ADDR_ASSERT_ALWAYS();
235 ADDR_ASSERT_ALWAYS();
244 // Pass createFlags to configFlags first since these flags may be overwritten
245 pLib
->m_configFlags
.noCubeMipSlicesPad
= pCreateIn
->createFlags
.noCubeMipSlicesPad
;
246 pLib
->m_configFlags
.fillSizeFields
= pCreateIn
->createFlags
.fillSizeFields
;
247 pLib
->m_configFlags
.useTileIndex
= pCreateIn
->createFlags
.useTileIndex
;
248 pLib
->m_configFlags
.useCombinedSwizzle
= pCreateIn
->createFlags
.useCombinedSwizzle
;
249 pLib
->m_configFlags
.checkLast2DLevel
= pCreateIn
->createFlags
.checkLast2DLevel
;
250 pLib
->m_configFlags
.useHtileSliceAlign
= pCreateIn
->createFlags
.useHtileSliceAlign
;
251 pLib
->m_configFlags
.allowLargeThickTile
= pCreateIn
->createFlags
.allowLargeThickTile
;
252 pLib
->m_configFlags
.forceDccAndTcCompat
= pCreateIn
->createFlags
.forceDccAndTcCompat
;
253 pLib
->m_configFlags
.disableLinearOpt
= FALSE
;
255 pLib
->SetChipFamily(pCreateIn
->chipFamily
, pCreateIn
->chipRevision
);
257 pLib
->SetMinPitchAlignPixels(pCreateIn
->minPitchAlignPixels
);
259 // Global parameters initialized and remaining configFlags bits are set as well
260 initValid
= pLib
->HwlInitGlobalParams(pCreateIn
);
264 pLib
->m_pElemLib
= ElemLib::Create(pLib
);
268 pLib
->m_pElemLib
= NULL
; // Don't go on allocating element lib
269 returnCode
= ADDR_INVALIDGBREGVALUES
;
272 if (pLib
->m_pElemLib
== NULL
)
276 ADDR_ASSERT_ALWAYS();
280 pLib
->m_pElemLib
->SetConfigFlags(pLib
->m_configFlags
);
284 pCreateOut
->hLib
= pLib
;
286 if ((pLib
!= NULL
) &&
287 (returnCode
== ADDR_OK
))
289 pCreateOut
->numEquations
=
290 pLib
->HwlGetEquationTableInfo(&pCreateOut
->pEquationTable
);
292 pLib
->SetMaxAlignments();
295 else if ((pLib
== NULL
) &&
296 (returnCode
== ADDR_OK
))
298 // Unknown failures, we return the general error code
299 returnCode
= ADDR_ERROR
;
306 ****************************************************************************************************
310 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
313 ****************************************************************************************************
315 VOID
Lib::SetChipFamily(
316 UINT_32 uChipFamily
, ///< [in] chip family defined in atiih.h
317 UINT_32 uChipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
319 ChipFamily family
= HwlConvertChipFamily(uChipFamily
, uChipRevision
);
321 ADDR_ASSERT(family
!= ADDR_CHIP_FAMILY_IVLD
);
323 m_chipFamily
= family
;
324 m_chipRevision
= uChipRevision
;
328 ****************************************************************************************************
329 * Lib::SetMinPitchAlignPixels
332 * Set m_minPitchAlignPixels with input param
336 ****************************************************************************************************
338 VOID
Lib::SetMinPitchAlignPixels(
339 UINT_32 minPitchAlignPixels
) ///< [in] minmum pitch alignment in pixels
341 m_minPitchAlignPixels
= (minPitchAlignPixels
== 0) ? 1 : minPitchAlignPixels
;
345 ****************************************************************************************************
346 * Lib::SetMaxAlignments
353 ****************************************************************************************************
355 VOID
Lib::SetMaxAlignments()
357 m_maxBaseAlign
= HwlComputeMaxBaseAlignments();
358 m_maxMetaBaseAlign
= HwlComputeMaxMetaBaseAlignments();
362 ****************************************************************************************************
366 * Get AddrLib pointer
369 * An AddrLib class pointer
370 ****************************************************************************************************
373 ADDR_HANDLE hLib
) ///< [in] handle of ADDR_HANDLE
375 return static_cast<Addr::Lib
*>(hLib
);
379 ****************************************************************************************************
380 * Lib::GetMaxAlignments
383 * Gets maximum alignments for data surface (include FMask)
387 ****************************************************************************************************
389 ADDR_E_RETURNCODE
Lib::GetMaxAlignments(
390 ADDR_GET_MAX_ALIGNMENTS_OUTPUT
* pOut
///< [out] output structure
393 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
395 if (GetFillSizeFieldsFlags() == TRUE
)
397 if (pOut
->size
!= sizeof(ADDR_GET_MAX_ALIGNMENTS_OUTPUT
))
399 returnCode
= ADDR_PARAMSIZEMISMATCH
;
403 if (returnCode
== ADDR_OK
)
405 if (m_maxBaseAlign
!= 0)
407 pOut
->baseAlign
= m_maxBaseAlign
;
411 returnCode
= ADDR_NOTIMPLEMENTED
;
419 ****************************************************************************************************
420 * Lib::GetMaxMetaAlignments
423 * Gets maximum alignments for metadata (CMask, DCC and HTile)
427 ****************************************************************************************************
429 ADDR_E_RETURNCODE
Lib::GetMaxMetaAlignments(
430 ADDR_GET_MAX_ALIGNMENTS_OUTPUT
* pOut
///< [out] output structure
433 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
435 if (GetFillSizeFieldsFlags() == TRUE
)
437 if (pOut
->size
!= sizeof(ADDR_GET_MAX_ALIGNMENTS_OUTPUT
))
439 returnCode
= ADDR_PARAMSIZEMISMATCH
;
443 if (returnCode
== ADDR_OK
)
445 if (m_maxMetaBaseAlign
!= 0)
447 pOut
->baseAlign
= m_maxMetaBaseAlign
;
451 returnCode
= ADDR_NOTIMPLEMENTED
;
459 ****************************************************************************************************
463 * Cat a array of binary bit to a number
466 * The number combined with the array of bits
467 ****************************************************************************************************
469 UINT_32
Lib::Bits2Number(
470 UINT_32 bitNum
, ///< [in] how many bits
471 ...) ///< [in] varaible bits value starting from MSB
477 va_start(bits_ptr
, bitNum
);
479 for(i
= 0; i
< bitNum
; i
++)
481 number
|= va_arg(bits_ptr
, UINT_32
);
492 ////////////////////////////////////////////////////////////////////////////////////////////////////
494 ////////////////////////////////////////////////////////////////////////////////////////////////////
497 ****************************************************************************************************
498 * Lib::Flt32ToColorPixel
501 * Convert a FLT_32 value to a depth/stencil pixel value
504 ****************************************************************************************************
506 ADDR_E_RETURNCODE
Lib::Flt32ToDepthPixel(
507 const ELEM_FLT32TODEPTHPIXEL_INPUT
* pIn
,
508 ELEM_FLT32TODEPTHPIXEL_OUTPUT
* pOut
) const
510 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
512 if (GetFillSizeFieldsFlags() == TRUE
)
514 if ((pIn
->size
!= sizeof(ELEM_FLT32TODEPTHPIXEL_INPUT
)) ||
515 (pOut
->size
!= sizeof(ELEM_FLT32TODEPTHPIXEL_OUTPUT
)))
517 returnCode
= ADDR_PARAMSIZEMISMATCH
;
521 if (returnCode
== ADDR_OK
)
523 GetElemLib()->Flt32ToDepthPixel(pIn
->format
, pIn
->comps
, pOut
->pPixel
);
525 UINT_32 depthBase
= 0;
526 UINT_32 stencilBase
= 0;
527 UINT_32 depthBits
= 0;
528 UINT_32 stencilBits
= 0;
535 case ADDR_DEPTH_X8_24
:
536 case ADDR_DEPTH_8_24
:
537 case ADDR_DEPTH_X8_24_FLOAT
:
538 case ADDR_DEPTH_8_24_FLOAT
:
543 case ADDR_DEPTH_32_FLOAT
:
546 case ADDR_DEPTH_X24_8_32_FLOAT
:
555 // Overwrite base since R800 has no "tileBase"
556 if (GetElemLib()->IsDepthStencilTilePlanar() == FALSE
)
565 pOut
->stencilBase
= stencilBase
;
566 pOut
->depthBase
= depthBase
;
567 pOut
->depthBits
= depthBits
;
568 pOut
->stencilBits
= stencilBits
;
575 ****************************************************************************************************
576 * Lib::Flt32ToColorPixel
579 * Convert a FLT_32 value to a red/green/blue/alpha pixel value
582 ****************************************************************************************************
584 ADDR_E_RETURNCODE
Lib::Flt32ToColorPixel(
585 const ELEM_FLT32TOCOLORPIXEL_INPUT
* pIn
,
586 ELEM_FLT32TOCOLORPIXEL_OUTPUT
* pOut
) const
588 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
590 if (GetFillSizeFieldsFlags() == TRUE
)
592 if ((pIn
->size
!= sizeof(ELEM_FLT32TOCOLORPIXEL_INPUT
)) ||
593 (pOut
->size
!= sizeof(ELEM_FLT32TOCOLORPIXEL_OUTPUT
)))
595 returnCode
= ADDR_PARAMSIZEMISMATCH
;
599 if (returnCode
== ADDR_OK
)
601 GetElemLib()->Flt32ToColorPixel(pIn
->format
,
612 ****************************************************************************************************
616 * Check one format can be EXPORT_NUM
618 * TRUE if EXPORT_NORM can be used
619 ****************************************************************************************************
621 BOOL_32
Lib::GetExportNorm(
622 const ELEM_GETEXPORTNORM_INPUT
* pIn
) const
624 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
626 BOOL_32 enabled
= FALSE
;
628 if (GetFillSizeFieldsFlags() == TRUE
)
630 if (pIn
->size
!= sizeof(ELEM_GETEXPORTNORM_INPUT
))
632 returnCode
= ADDR_PARAMSIZEMISMATCH
;
636 if (returnCode
== ADDR_OK
)
638 enabled
= GetElemLib()->PixGetExportNorm(pIn
->format
, pIn
->num
, pIn
->swap
);
645 ****************************************************************************************************
649 * Get bits-per-element for specified format
651 * bits-per-element of specified format
652 ****************************************************************************************************
654 UINT_32
Lib::GetBpe(AddrFormat format
) const
656 return GetElemLib()->GetBitsPerPixel(format
);