2 * Copyright © 2017 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 AddrLib2 base class.
31 ****************************************************************************************************
34 #include "addrinterface.h"
36 #include "addrcommon.h"
43 ////////////////////////////////////////////////////////////////////////////////////////////////////
44 // Static Const Member
45 ////////////////////////////////////////////////////////////////////////////////////////////////////
47 const SwizzleModeFlags
Lib::SwizzleModeTable
[ADDR_SW_MAX_TYPE
] =
48 {//Linear 256B 4KB 64KB Var Z Std Disp Rot XOR T
49 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},//ADDR_SW_LINEAR
50 {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0},//ADDR_SW_256B_S
51 {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0},//ADDR_SW_256B_D
52 {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0},//ADDR_SW_256B_R
54 {0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0},//ADDR_SW_4KB_Z
55 {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0},//ADDR_SW_4KB_S
56 {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0},//ADDR_SW_4KB_D
57 {0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0},//ADDR_SW_4KB_R
59 {0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0},//ADDR_SW_64KB_Z
60 {0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0},//ADDR_SW_64KB_S
61 {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0},//ADDR_SW_64KB_D
62 {0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0},//ADDR_SW_64KB_R
64 {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0},//ADDR_SW_VAR_Z
65 {0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0},//ADDR_SW_VAR_S
66 {0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0},//ADDR_SW_VAR_D
67 {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0},//ADDR_SW_VAR_R
69 {0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1},//ADDR_SW_64KB_Z_T
70 {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1},//ADDR_SW_64KB_S_T
71 {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1},//ADDR_SW_64KB_D_T
72 {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1},//ADDR_SW_64KB_R_T
74 {0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0},//ADDR_SW_4KB_Z_x
75 {0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0},//ADDR_SW_4KB_S_x
76 {0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0},//ADDR_SW_4KB_D_x
77 {0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0},//ADDR_SW_4KB_R_x
79 {0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0},//ADDR_SW_64KB_Z_X
80 {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0},//ADDR_SW_64KB_S_X
81 {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0},//ADDR_SW_64KB_D_X
82 {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0},//ADDR_SW_64KB_R_X
84 {0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0},//ADDR_SW_VAR_Z_X
85 {0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0},//ADDR_SW_VAR_S_X
86 {0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0},//ADDR_SW_VAR_D_X
87 {0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0},//ADDR_SW_VAR_R_X
88 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},//ADDR_SW_LINEAR_GENERAL
91 const Dim2d
Lib::Block256b
[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}};
93 const Dim3d
Lib::Block1kb
[] = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}};
95 const Dim2d
Lib::CompressBlock2d
[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}};
97 const Dim3d
Lib::CompressBlock3dS
[] = {{16, 4, 4}, {8, 4, 4}, {4, 4, 4}, {2, 4, 4}, {1, 4, 4}};
99 const Dim3d
Lib::CompressBlock3dZ
[] = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}};
101 const UINT_32
Lib::MaxMacroBits
= 20;
103 const UINT_32
Lib::MipTailOffset
[] = {2048, 1024, 512, 256, 128, 64, 32, 16,
104 8, 6, 5, 4, 3, 2, 1, 0};
106 ////////////////////////////////////////////////////////////////////////////////////////////////////
107 // Constructor/Destructor
108 ////////////////////////////////////////////////////////////////////////////////////////////////////
111 ****************************************************************************************************
115 * Constructor for the Addr::V2::Lib class
117 ****************************************************************************************************
126 ****************************************************************************************************
130 * Constructor for the AddrLib2 class with hClient as parameter
132 ****************************************************************************************************
134 Lib::Lib(const Client
* pClient
)
141 ****************************************************************************************************
145 * Destructor for the AddrLib2 class
147 ****************************************************************************************************
154 ****************************************************************************************************
158 * Get Addr::V2::Lib pointer
161 * An Addr::V2::Lib class pointer
162 ****************************************************************************************************
165 ADDR_HANDLE hLib
) ///< [in] handle of ADDR_HANDLE
167 Addr::Lib
* pAddrLib
= Addr::Lib::GetLib(hLib
);
168 if ((pAddrLib
!= NULL
) &&
169 (pAddrLib
->GetChipFamily() <= ADDR_CHIP_FAMILY_VI
))
171 // only valid and GFX9+ AISC can use AddrLib2 function.
172 ADDR_ASSERT_ALWAYS();
175 return static_cast<Lib
*>(hLib
);
179 ////////////////////////////////////////////////////////////////////////////////////////////////////
181 ////////////////////////////////////////////////////////////////////////////////////////////////////
185 ****************************************************************************************************
186 * Lib::ComputeSurfaceInfo
189 * Interface function stub of AddrComputeSurfaceInfo.
193 ****************************************************************************************************
195 ADDR_E_RETURNCODE
Lib::ComputeSurfaceInfo(
196 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
197 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
200 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
202 if (GetFillSizeFieldsFlags() == TRUE
)
204 if ((pIn
->size
!= sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT
)) ||
205 (pOut
->size
!= sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
)))
207 returnCode
= ADDR_PARAMSIZEMISMATCH
;
211 // Adjust coming parameters.
212 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= *pIn
;
213 localIn
.width
= Max(pIn
->width
, 1u);
214 localIn
.height
= Max(pIn
->height
, 1u);
215 localIn
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
216 localIn
.numSlices
= Max(pIn
->numSlices
, 1u);
217 localIn
.numSamples
= Max(pIn
->numSamples
, 1u);
218 localIn
.numFrags
= (localIn
.numFrags
== 0) ? localIn
.numSamples
: pIn
->numFrags
;
222 ElemMode elemMode
= ADDR_UNCOMPRESSED
;
224 if (returnCode
== ADDR_OK
)
226 // Set format to INVALID will skip this conversion
227 if (localIn
.format
!= ADDR_FMT_INVALID
)
229 // Get compression/expansion factors and element mode which indicates compression/expansion
230 localIn
.bpp
= GetElemLib()->GetBitsPerPixel(localIn
.format
,
235 // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
236 // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
237 // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
238 // restrictions are different.
239 // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
240 // but we use this flag to skip RestoreSurfaceInfo below
242 if ((elemMode
== ADDR_EXPANDED
) && (expandX
> 1))
244 ADDR_ASSERT((localIn
.swizzleMode
== ADDR_SW_LINEAR
) || (localIn
.height
== 1));
247 UINT_32 basePitch
= 0;
248 GetElemLib()->AdjustSurfaceInfo(elemMode
,
256 // Overwrite these parameters if we have a valid format
259 if (localIn
.bpp
!= 0)
261 localIn
.width
= Max(localIn
.width
, 1u);
262 localIn
.height
= Max(localIn
.height
, 1u);
264 else // Rule out some invalid parameters
266 ADDR_ASSERT_ALWAYS();
268 returnCode
= ADDR_INVALIDPARAMS
;
272 if (returnCode
== ADDR_OK
)
274 returnCode
= ComputeSurfaceInfoSanityCheck(&localIn
);
277 if (returnCode
== ADDR_OK
)
279 VerifyMipLevelInfo(pIn
);
281 if (IsLinear(pIn
->swizzleMode
))
284 returnCode
= ComputeSurfaceInfoLinear(&localIn
, pOut
);
289 returnCode
= ComputeSurfaceInfoTiled(&localIn
, pOut
);
292 if (returnCode
== ADDR_OK
)
294 pOut
->bpp
= localIn
.bpp
;
295 pOut
->pixelPitch
= pOut
->pitch
;
296 pOut
->pixelHeight
= pOut
->height
;
297 pOut
->pixelMipChainPitch
= pOut
->mipChainPitch
;
298 pOut
->pixelMipChainHeight
= pOut
->mipChainHeight
;
299 pOut
->pixelBits
= localIn
.bpp
;
301 if (localIn
.format
!= ADDR_FMT_INVALID
)
303 UINT_32 pixelBits
= pOut
->pixelBits
;
305 GetElemLib()->RestoreSurfaceInfo(elemMode
,
312 GetElemLib()->RestoreSurfaceInfo(elemMode
,
316 &pOut
->pixelMipChainPitch
,
317 &pOut
->pixelMipChainHeight
);
320 if (localIn
.flags
.needEquation
&& (Log2(localIn
.numFrags
) == 0))
322 pOut
->equationIndex
= GetEquationIndex(&localIn
, pOut
);
331 ****************************************************************************************************
332 * Lib::ComputeSurfaceInfo
335 * Interface function stub of AddrComputeSurfaceInfo.
339 ****************************************************************************************************
341 ADDR_E_RETURNCODE
Lib::ComputeSurfaceAddrFromCoord(
342 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
343 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
346 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
348 if (GetFillSizeFieldsFlags() == TRUE
)
350 if ((pIn
->size
!= sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
)) ||
351 (pOut
->size
!= sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
)))
353 returnCode
= ADDR_PARAMSIZEMISMATCH
;
357 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn
= *pIn
;
358 localIn
.unalignedWidth
= Max(pIn
->unalignedWidth
, 1u);
359 localIn
.unalignedHeight
= Max(pIn
->unalignedHeight
, 1u);
360 localIn
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
361 localIn
.numSlices
= Max(pIn
->numSlices
, 1u);
362 localIn
.numSamples
= Max(pIn
->numSamples
, 1u);
363 localIn
.numFrags
= Max(pIn
->numFrags
, 1u);
365 if ((localIn
.bpp
< 8) ||
366 (localIn
.bpp
> 128) ||
367 ((localIn
.bpp
% 8) != 0) ||
368 (localIn
.sample
>= localIn
.numSamples
) ||
369 (localIn
.slice
>= localIn
.numSlices
) ||
370 (localIn
.mipId
>= localIn
.numMipLevels
) ||
371 (IsTex3d(localIn
.resourceType
) &&
372 (Valid3DMipSliceIdConstraint(localIn
.numSlices
, localIn
.mipId
, localIn
.slice
) == FALSE
)))
374 returnCode
= ADDR_INVALIDPARAMS
;
377 if (returnCode
== ADDR_OK
)
379 if (IsLinear(localIn
.swizzleMode
))
381 returnCode
= ComputeSurfaceAddrFromCoordLinear(&localIn
, pOut
);
385 returnCode
= ComputeSurfaceAddrFromCoordTiled(&localIn
, pOut
);
393 ****************************************************************************************************
394 * Lib::ComputeSurfaceCoordFromAddr
397 * Interface function stub of ComputeSurfaceCoordFromAddr.
401 ****************************************************************************************************
403 ADDR_E_RETURNCODE
Lib::ComputeSurfaceCoordFromAddr(
404 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
405 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
408 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
410 if (GetFillSizeFieldsFlags() == TRUE
)
412 if ((pIn
->size
!= sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT
)) ||
413 (pOut
->size
!= sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
)))
415 returnCode
= ADDR_PARAMSIZEMISMATCH
;
419 if ((pIn
->bpp
< 8) ||
421 ((pIn
->bpp
% 8) != 0) ||
422 (pIn
->bitPosition
>= 8))
424 returnCode
= ADDR_INVALIDPARAMS
;
427 if (returnCode
== ADDR_OK
)
429 if (IsLinear(pIn
->swizzleMode
))
431 returnCode
= ComputeSurfaceCoordFromAddrLinear(pIn
, pOut
);
435 returnCode
= ComputeSurfaceCoordFromAddrTiled(pIn
, pOut
);
443 ////////////////////////////////////////////////////////////////////////////////////////////////////
445 ////////////////////////////////////////////////////////////////////////////////////////////////////
448 ****************************************************************************************************
449 * Lib::ComputeHtileInfo
452 * Interface function stub of AddrComputeHtilenfo
456 ****************************************************************************************************
458 ADDR_E_RETURNCODE
Lib::ComputeHtileInfo(
459 const ADDR2_COMPUTE_HTILE_INFO_INPUT
* pIn
, ///< [in] input structure
460 ADDR2_COMPUTE_HTILE_INFO_OUTPUT
* pOut
///< [out] output structure
463 ADDR_E_RETURNCODE returnCode
;
465 if ((GetFillSizeFieldsFlags() == TRUE
) &&
466 ((pIn
->size
!= sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT
)) ||
467 (pOut
->size
!= sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT
))))
469 returnCode
= ADDR_INVALIDPARAMS
;
473 returnCode
= HwlComputeHtileInfo(pIn
, pOut
);
480 ****************************************************************************************************
481 * Lib::ComputeHtileAddrFromCoord
484 * Interface function stub of AddrComputeHtileAddrFromCoord
488 ****************************************************************************************************
490 ADDR_E_RETURNCODE
Lib::ComputeHtileAddrFromCoord(
491 const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
492 ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
495 ADDR_E_RETURNCODE returnCode
;
497 if ((GetFillSizeFieldsFlags() == TRUE
) &&
498 ((pIn
->size
!= sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
)) ||
499 (pOut
->size
!= sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
))))
501 returnCode
= ADDR_INVALIDPARAMS
;
505 returnCode
= HwlComputeHtileAddrFromCoord(pIn
, pOut
);
512 ****************************************************************************************************
513 * Lib::ComputeHtileCoordFromAddr
516 * Interface function stub of AddrComputeHtileCoordFromAddr
520 ****************************************************************************************************
522 ADDR_E_RETURNCODE
Lib::ComputeHtileCoordFromAddr(
523 const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
524 ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
527 ADDR_E_RETURNCODE returnCode
;
529 if ((GetFillSizeFieldsFlags() == TRUE
) &&
530 ((pIn
->size
!= sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT
)) ||
531 (pOut
->size
!= sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
))))
533 returnCode
= ADDR_INVALIDPARAMS
;
537 returnCode
= HwlComputeHtileCoordFromAddr(pIn
, pOut
);
544 ****************************************************************************************************
545 * Lib::ComputeCmaskInfo
548 * Interface function stub of AddrComputeCmaskInfo
552 ****************************************************************************************************
554 ADDR_E_RETURNCODE
Lib::ComputeCmaskInfo(
555 const ADDR2_COMPUTE_CMASK_INFO_INPUT
* pIn
, ///< [in] input structure
556 ADDR2_COMPUTE_CMASK_INFO_OUTPUT
* pOut
///< [out] output structure
559 ADDR_E_RETURNCODE returnCode
;
561 if ((GetFillSizeFieldsFlags() == TRUE
) &&
562 ((pIn
->size
!= sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT
)) ||
563 (pOut
->size
!= sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT
))))
565 returnCode
= ADDR_INVALIDPARAMS
;
567 else if (pIn
->cMaskFlags
.linear
)
569 returnCode
= ADDR_INVALIDPARAMS
;
573 returnCode
= HwlComputeCmaskInfo(pIn
, pOut
);
580 ****************************************************************************************************
581 * Lib::ComputeCmaskAddrFromCoord
584 * Interface function stub of AddrComputeCmaskAddrFromCoord
588 ****************************************************************************************************
590 ADDR_E_RETURNCODE
Lib::ComputeCmaskAddrFromCoord(
591 const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
592 ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
595 ADDR_E_RETURNCODE returnCode
;
597 if ((GetFillSizeFieldsFlags() == TRUE
) &&
598 ((pIn
->size
!= sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
)) ||
599 (pOut
->size
!= sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
))))
601 returnCode
= ADDR_INVALIDPARAMS
;
605 returnCode
= HwlComputeCmaskAddrFromCoord(pIn
, pOut
);
612 ****************************************************************************************************
613 * Lib::ComputeCmaskCoordFromAddr
616 * Interface function stub of AddrComputeCmaskCoordFromAddr
620 ****************************************************************************************************
622 ADDR_E_RETURNCODE
Lib::ComputeCmaskCoordFromAddr(
623 const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
624 ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
627 ADDR_E_RETURNCODE returnCode
= ADDR_NOTIMPLEMENTED
;
629 ADDR_NOT_IMPLEMENTED();
635 ****************************************************************************************************
636 * Lib::ComputeFmaskInfo
639 * Interface function stub of ComputeFmaskInfo.
643 ****************************************************************************************************
645 ADDR_E_RETURNCODE
Lib::ComputeFmaskInfo(
646 const ADDR2_COMPUTE_FMASK_INFO_INPUT
* pIn
, ///< [in] input structure
647 ADDR2_COMPUTE_FMASK_INFO_OUTPUT
* pOut
///< [out] output structure
650 ADDR_E_RETURNCODE returnCode
;
652 BOOL_32 valid
= (IsZOrderSwizzle(pIn
->swizzleMode
) == TRUE
) &&
653 ((pIn
->numSamples
> 0) || (pIn
->numFrags
> 0));
655 if (GetFillSizeFieldsFlags())
657 if ((pIn
->size
!= sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT
)) ||
658 (pOut
->size
!= sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT
)))
666 returnCode
= ADDR_INVALIDPARAMS
;
670 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {0};
671 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut
= {0};
673 localIn
.size
= sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT
);
674 localOut
.size
= sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
);
676 localIn
.swizzleMode
= pIn
->swizzleMode
;
677 localIn
.numSlices
= Max(pIn
->numSlices
, 1u);
678 localIn
.width
= Max(pIn
->unalignedWidth
, 1u);
679 localIn
.height
= Max(pIn
->unalignedHeight
, 1u);
680 localIn
.bpp
= GetFmaskBpp(pIn
->numSamples
, pIn
->numFrags
);
681 localIn
.flags
.fmask
= 1;
682 localIn
.numFrags
= 1;
683 localIn
.numSamples
= 1;
684 localIn
.resourceType
= ADDR_RSRC_TEX_2D
;
686 if (localIn
.bpp
== 8)
688 localIn
.format
= ADDR_FMT_8
;
690 else if (localIn
.bpp
== 16)
692 localIn
.format
= ADDR_FMT_16
;
694 else if (localIn
.bpp
== 32)
696 localIn
.format
= ADDR_FMT_32
;
700 localIn
.format
= ADDR_FMT_32_32
;
703 returnCode
= ComputeSurfaceInfo(&localIn
, &localOut
);
705 if (returnCode
== ADDR_OK
)
707 pOut
->pitch
= localOut
.pitch
;
708 pOut
->height
= localOut
.height
;
709 pOut
->baseAlign
= localOut
.baseAlign
;
710 pOut
->numSlices
= localOut
.numSlices
;
711 pOut
->fmaskBytes
= static_cast<UINT_32
>(localOut
.surfSize
);
712 pOut
->sliceSize
= localOut
.sliceSize
;
713 pOut
->bpp
= localIn
.bpp
;
714 pOut
->numSamples
= 1;
722 ****************************************************************************************************
723 * Lib::ComputeFmaskAddrFromCoord
726 * Interface function stub of ComputeFmaskAddrFromCoord.
730 ****************************************************************************************************
732 ADDR_E_RETURNCODE
Lib::ComputeFmaskAddrFromCoord(
733 const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
734 ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
737 ADDR_E_RETURNCODE returnCode
= ADDR_NOTIMPLEMENTED
;
739 ADDR_NOT_IMPLEMENTED();
745 ****************************************************************************************************
746 * Lib::ComputeFmaskCoordFromAddr
749 * Interface function stub of ComputeFmaskAddrFromCoord.
753 ****************************************************************************************************
755 ADDR_E_RETURNCODE
Lib::ComputeFmaskCoordFromAddr(
756 const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
757 ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
760 ADDR_E_RETURNCODE returnCode
= ADDR_NOTIMPLEMENTED
;
762 ADDR_NOT_IMPLEMENTED();
768 ****************************************************************************************************
769 * Lib::GetMetaMiptailInfo
772 * Get mip tail coordinate information.
776 ****************************************************************************************************
778 VOID
Lib::GetMetaMiptailInfo(
779 ADDR2_META_MIP_INFO
* pInfo
, ///< [out] output structure to store per mip coord
780 Dim3d mipCoord
, ///< [in] mip tail base coord
781 UINT_32 numMipInTail
, ///< [in] number of mips in tail
782 Dim3d
* pMetaBlkDim
///< [in] meta block width/height/depth
785 BOOL_32 isThick
= (pMetaBlkDim
->d
> 1);
786 UINT_32 mipWidth
= pMetaBlkDim
->w
;
787 UINT_32 mipHeight
= pMetaBlkDim
->h
>> 1;
788 UINT_32 mipDepth
= pMetaBlkDim
->d
;
793 minInc
= (pMetaBlkDim
->h
>= 512) ? 128 : ((pMetaBlkDim
->h
== 256) ? 64 : 32);
795 else if (pMetaBlkDim
->h
>= 1024)
799 else if (pMetaBlkDim
->h
== 512)
808 UINT_32 blk32MipId
= 0xFFFFFFFF;
810 for (UINT_32 mip
= 0; mip
< numMipInTail
; mip
++)
812 pInfo
[mip
].inMiptail
= TRUE
;
813 pInfo
[mip
].startX
= mipCoord
.w
;
814 pInfo
[mip
].startY
= mipCoord
.h
;
815 pInfo
[mip
].startZ
= mipCoord
.d
;
816 pInfo
[mip
].width
= mipWidth
;
817 pInfo
[mip
].height
= mipHeight
;
818 pInfo
[mip
].depth
= mipDepth
;
822 if (blk32MipId
== 0xFFFFFFFF)
827 mipCoord
.w
= pInfo
[blk32MipId
].startX
;
828 mipCoord
.h
= pInfo
[blk32MipId
].startY
;
829 mipCoord
.d
= pInfo
[blk32MipId
].startZ
;
831 switch (mip
- blk32MipId
)
834 mipCoord
.w
+= 32; // 16x16
837 mipCoord
.h
+= 32; // 8x8
840 mipCoord
.h
+= 32; // 4x4
844 mipCoord
.h
+= 32; // 2x2
848 mipCoord
.h
+= 32; // 1x1
851 // The following are for BC/ASTC formats
853 mipCoord
.h
+= 48; // 1/2 x 1/2
856 mipCoord
.h
+= 48; // 1/4 x 1/4
860 mipCoord
.h
+= 48; // 1/8 x 1/8
864 mipCoord
.h
+= 48; // 1/16 x 1/16
868 ADDR_ASSERT_ALWAYS();
872 mipWidth
= ((mip
- blk32MipId
) == 0) ? 16 : 8;
873 mipHeight
= mipWidth
;
882 if (mipWidth
<= minInc
)
884 // if we're below the minimal increment...
887 // For 3d, just go in z direction
888 mipCoord
.d
+= mipDepth
;
892 // For 2d, first go across, then down
893 if ((mipWidth
* 2) == minInc
)
895 // if we're 2 mips below, that's when we go back in x, and down in y
896 mipCoord
.w
-= minInc
;
897 mipCoord
.h
+= minInc
;
901 // otherwise, just go across in x
902 mipCoord
.w
+= minInc
;
908 // On even mip, go down, otherwise, go across
911 mipCoord
.w
+= mipWidth
;
915 mipCoord
.h
+= mipHeight
;
918 // Divide the width by 2
920 // After the first mip in tail, the mip is always a square
921 mipHeight
= mipWidth
;
922 // ...or for 3d, a cube
932 ****************************************************************************************************
933 * Lib::ComputeDccInfo
936 * Interface function to compute DCC key info
939 * return code of HwlComputeDccInfo
940 ****************************************************************************************************
942 ADDR_E_RETURNCODE
Lib::ComputeDccInfo(
943 const ADDR2_COMPUTE_DCCINFO_INPUT
* pIn
, ///< [in] input structure
944 ADDR2_COMPUTE_DCCINFO_OUTPUT
* pOut
///< [out] output structure
947 ADDR_E_RETURNCODE returnCode
;
949 if ((GetFillSizeFieldsFlags() == TRUE
) &&
950 ((pIn
->size
!= sizeof(ADDR2_COMPUTE_DCCINFO_INPUT
)) ||
951 (pOut
->size
!= sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT
))))
953 returnCode
= ADDR_INVALIDPARAMS
;
957 returnCode
= HwlComputeDccInfo(pIn
, pOut
);
964 ****************************************************************************************************
965 * Lib::ComputePipeBankXor
968 * Interface function stub of Addr2ComputePipeBankXor.
972 ****************************************************************************************************
974 ADDR_E_RETURNCODE
Lib::ComputePipeBankXor(
975 const ADDR2_COMPUTE_PIPEBANKXOR_INPUT
* pIn
,
976 ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT
* pOut
)
978 ADDR_E_RETURNCODE returnCode
;
980 if ((GetFillSizeFieldsFlags() == TRUE
) &&
981 ((pIn
->size
!= sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT
)) ||
982 (pOut
->size
!= sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT
))))
984 returnCode
= ADDR_INVALIDPARAMS
;
988 UINT_32 macroBlockBits
= GetBlockSizeLog2(pIn
->swizzleMode
);
989 UINT_32 pipeBits
= GetPipeXorBits(macroBlockBits
);
990 UINT_32 bankBits
= GetBankXorBits(macroBlockBits
);
996 UINT_32 bankMask
= (1 << bankBits
) - 1;
997 UINT_32 bankIncrease
= (1 << (bankBits
- 1)) - 1;
998 bankIncrease
= (bankIncrease
== 0) ? 1 : bankIncrease
;
999 bankXor
= ((pIn
->surfIndex
& bankMask
) * bankIncrease
) & bankMask
;
1004 UINT_32 pipeMask
= (1 << pipeBits
) - 1;
1005 UINT_32 pipeIncrease
= ((1 << (pipeBits
- 1)) + 1) & pipeMask
;
1006 pipeIncrease
= (pipeIncrease
== 0) ? 1 : pipeIncrease
;
1007 pipeXor
= ((pIn
->surfIndex
& pipeMask
) * pipeIncrease
) & pipeMask
;
1010 // Todo - pOut->pipeBankXor = pOut->pipeBankXor << (PipeInterleaveLog2 - 8)
1011 pOut
->pipeBankXor
= (bankXor
<< pipeBits
) | pipeXor
;
1013 returnCode
= ADDR_OK
;
1020 ****************************************************************************************************
1021 * Lib::ExtractPipeBankXor
1024 * Internal function to extract bank and pipe xor bits from combined xor bits.
1028 ****************************************************************************************************
1030 ADDR_E_RETURNCODE
Lib::ExtractPipeBankXor(
1031 UINT_32 pipeBankXor
,
1037 ADDR_E_RETURNCODE returnCode
;
1039 if (pipeBankXor
< (1u << (pipeBits
+ bankBits
)))
1041 *pPipeX
= pipeBankXor
% (1 << pipeBits
);
1042 *pBankX
= pipeBankXor
>> pipeBits
;
1043 returnCode
= ADDR_OK
;
1047 ADDR_ASSERT_ALWAYS();
1048 returnCode
= ADDR_INVALIDPARAMS
;
1055 ****************************************************************************************************
1056 * Lib::ComputeSurfaceInfoSanityCheck
1059 * Internal function to do basic sanity check before compute surface info
1063 ****************************************************************************************************
1065 ADDR_E_RETURNCODE
Lib::ComputeSurfaceInfoSanityCheck(
1066 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in] input structure
1069 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1071 BOOL_32 invalid
= FALSE
;
1073 if ((pIn
->bpp
> 128) || (pIn
->width
== 0) || (pIn
->numFrags
> 8) || (pIn
->numSamples
> 16))
1077 else if ((pIn
->swizzleMode
>= ADDR_SW_MAX_TYPE
) ||
1078 (pIn
->resourceType
>= ADDR_RSRC_MAX_TYPE
))
1083 BOOL_32 mipmap
= (pIn
->numMipLevels
> 1);
1084 BOOL_32 msaa
= (pIn
->numFrags
> 1);
1086 ADDR2_SURFACE_FLAGS flags
= pIn
->flags
;
1087 BOOL_32 zbuffer
= (flags
.depth
|| flags
.stencil
);
1088 BOOL_32 color
= flags
.color
;
1089 BOOL_32 display
= flags
.display
|| flags
.rotated
;
1091 AddrResourceType rsrcType
= pIn
->resourceType
;
1092 BOOL_32 tex3d
= IsTex3d(rsrcType
);
1094 AddrSwizzleMode swizzle
= pIn
->swizzleMode
;
1095 BOOL_32 linear
= IsLinear(swizzle
);
1096 BOOL_32 blk256B
= IsBlock256b(swizzle
);
1097 BOOL_32 blkVar
= IsBlockVariable(swizzle
);
1098 BOOL_32 isNonPrtXor
= IsNonPrtXor(swizzle
);
1099 BOOL_32 prt
= pIn
->flags
.prt
;
1101 if (invalid
== FALSE
)
1103 if ((pIn
->numFrags
> 1) &&
1104 (GetBlockSize(swizzle
) < (m_pipeInterleaveBytes
* pIn
->numFrags
)))
1106 // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
1111 if (invalid
== FALSE
)
1115 case ADDR_RSRC_TEX_1D
:
1116 invalid
= msaa
|| zbuffer
|| display
|| (linear
== FALSE
);
1118 case ADDR_RSRC_TEX_2D
:
1119 invalid
= msaa
&& mipmap
;
1121 case ADDR_RSRC_TEX_3D
:
1122 invalid
= msaa
|| zbuffer
|| display
;
1130 if (invalid
== FALSE
)
1134 invalid
= (IsValidDisplaySwizzleMode(pIn
) == FALSE
);
1138 if (invalid
== FALSE
)
1142 invalid
= prt
|| zbuffer
|| msaa
|| (pIn
->bpp
== 0) || ((pIn
->bpp
% 8) != 0);
1146 if (blk256B
|| blkVar
|| isNonPrtXor
)
1151 invalid
= invalid
|| zbuffer
|| tex3d
|| mipmap
|| msaa
;
1155 if (invalid
== FALSE
)
1157 if (IsZOrderSwizzle(swizzle
))
1159 invalid
= color
&& msaa
;
1161 else if (IsStandardSwizzle(rsrcType
, swizzle
))
1165 else if (IsDisplaySwizzle(rsrcType
, swizzle
))
1169 else if (IsRotateSwizzle(swizzle
))
1171 invalid
= zbuffer
|| (pIn
->bpp
> 64);
1175 ADDR_ASSERT(!"invalid swizzle mode");
1184 returnCode
= ADDR_INVALIDPARAMS
;
1191 ****************************************************************************************************
1192 * Lib::ApplyCustomizedPitchHeight
1195 * Helper function to override hw required row pitch/slice pitch by customrized one
1199 ****************************************************************************************************
1201 ADDR_E_RETURNCODE
Lib::ApplyCustomizedPitchHeight(
1202 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
1203 UINT_32 elementBytes
, ///< [in] element bytes per element
1204 UINT_32 widthAlignInElement
, ///< [in] pitch alignment in element
1205 UINT_32
* pPitch
, ///< [in/out] pitch
1206 UINT_32
* pHeight
///< [in/out] height
1209 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1211 if (pIn
->numMipLevels
<= 1)
1213 if (pIn
->pitchInElement
> 0)
1215 if ((pIn
->pitchInElement
% widthAlignInElement
) != 0)
1217 returnCode
= ADDR_INVALIDPARAMS
;
1219 else if (pIn
->pitchInElement
< (*pPitch
))
1221 returnCode
= ADDR_INVALIDPARAMS
;
1225 *pPitch
= pIn
->pitchInElement
;
1229 if (returnCode
== ADDR_OK
)
1231 if (pIn
->sliceAlign
> 0)
1233 UINT_32 customizedHeight
= pIn
->sliceAlign
/ elementBytes
/ (*pPitch
);
1235 if (customizedHeight
* elementBytes
* (*pPitch
) != pIn
->sliceAlign
)
1237 returnCode
= ADDR_INVALIDPARAMS
;
1239 else if ((pIn
->numSlices
> 1) && ((*pHeight
) != customizedHeight
))
1241 returnCode
= ADDR_INVALIDPARAMS
;
1245 *pHeight
= customizedHeight
;
1255 ****************************************************************************************************
1256 * Lib::ComputeSurfaceInfoLinear
1259 * Internal function to calculate alignment for linear swizzle surface
1263 ****************************************************************************************************
1265 ADDR_E_RETURNCODE
Lib::ComputeSurfaceInfoLinear(
1266 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
1267 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
1270 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1273 UINT_32 actualHeight
= 0;
1274 UINT_32 elementBytes
= pIn
->bpp
>> 3;
1276 if (IsTex1d(pIn
->resourceType
))
1278 if (pIn
->height
> 1)
1280 returnCode
= ADDR_INVALIDPARAMS
;
1284 const UINT_32 widthAlignInElement
= 256 / elementBytes
;
1285 pitch
= PowTwoAlign(pIn
->width
, widthAlignInElement
);
1286 actualHeight
= pIn
->numMipLevels
;
1287 returnCode
= ApplyCustomizedPitchHeight(pIn
, elementBytes
, widthAlignInElement
,
1288 &pitch
, &actualHeight
);
1290 if (returnCode
== ADDR_OK
)
1292 if (pOut
->pMipInfo
!= NULL
)
1294 for (UINT_32 i
= 0; i
< pIn
->numMipLevels
; i
++)
1296 pOut
->pMipInfo
[i
].offset
= pitch
* elementBytes
* i
;
1297 pOut
->pMipInfo
[i
].pitch
= pitch
;
1298 pOut
->pMipInfo
[i
].height
= 1;
1299 pOut
->pMipInfo
[i
].depth
= 1;
1307 returnCode
= ComputeSurfaceLinearPadding(pIn
, &pitch
, &actualHeight
, pOut
->pMipInfo
);
1310 if ((pitch
== 0) || (actualHeight
== 0))
1312 returnCode
= ADDR_INVALIDPARAMS
;
1315 if (returnCode
== ADDR_OK
)
1317 pOut
->pitch
= pitch
;
1318 pOut
->height
= pIn
->height
;
1319 pOut
->numSlices
= pIn
->numSlices
;
1320 pOut
->mipChainPitch
= pitch
;
1321 pOut
->mipChainHeight
= actualHeight
;
1322 pOut
->mipChainSlice
= pOut
->numSlices
;
1323 pOut
->epitchIsHeight
= (pIn
->numMipLevels
> 1) ? TRUE
: FALSE
;
1324 pOut
->sliceSize
= pOut
->pitch
* actualHeight
* elementBytes
;
1325 pOut
->surfSize
= pOut
->sliceSize
* pOut
->numSlices
;
1326 pOut
->baseAlign
= (pIn
->swizzleMode
== ADDR_SW_LINEAR_GENERAL
) ? (pIn
->bpp
/ 8) : 256;
1327 pOut
->blockWidth
= (pIn
->swizzleMode
== ADDR_SW_LINEAR_GENERAL
) ? 1 : (256 * 8 / pIn
->bpp
);
1328 pOut
->blockHeight
= 1;
1329 pOut
->blockSlices
= 1;
1332 // Post calculation validate
1333 ADDR_ASSERT((pOut
->sliceSize
> 0));
1339 ****************************************************************************************************
1340 * Lib::ComputeSurfaceInfoTiled
1343 * Internal function to calculate alignment for tiled swizzle surface
1347 ****************************************************************************************************
1349 ADDR_E_RETURNCODE
Lib::ComputeSurfaceInfoTiled(
1350 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
1351 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
1354 ADDR_E_RETURNCODE returnCode
= ComputeBlockDimensionForSurf(&pOut
->blockWidth
,
1362 if (returnCode
== ADDR_OK
)
1364 const UINT_32 widthAlignInElement
= pOut
->blockWidth
;
1366 pOut
->pitch
= PowTwoAlign(pIn
->width
, widthAlignInElement
);
1368 if ((pIn
->numMipLevels
<= 1) && (pIn
->pitchInElement
> 0))
1370 if ((pIn
->pitchInElement
% widthAlignInElement
) != 0)
1372 returnCode
= ADDR_INVALIDPARAMS
;
1374 else if (pIn
->pitchInElement
< pOut
->pitch
)
1376 returnCode
= ADDR_INVALIDPARAMS
;
1380 pOut
->pitch
= pIn
->pitchInElement
;
1384 if (returnCode
== ADDR_OK
)
1386 pOut
->height
= PowTwoAlign(pIn
->height
, pOut
->blockHeight
);
1387 pOut
->numSlices
= PowTwoAlign(pIn
->numSlices
, pOut
->blockSlices
);
1389 pOut
->epitchIsHeight
= FALSE
;
1390 pOut
->firstMipInTail
= FALSE
;
1392 pOut
->mipChainPitch
= pOut
->pitch
;
1393 pOut
->mipChainHeight
= pOut
->height
;
1394 pOut
->mipChainSlice
= pOut
->numSlices
;
1396 if (pIn
->numMipLevels
> 1)
1398 UINT_32 numMipLevel
;
1399 ADDR2_MIP_INFO
*pMipInfo
;
1400 ADDR2_MIP_INFO mipInfo
[4];
1402 if (pOut
->pMipInfo
!= NULL
)
1404 pMipInfo
= pOut
->pMipInfo
;
1405 numMipLevel
= pIn
->numMipLevels
;
1410 numMipLevel
= Min(pIn
->numMipLevels
, 4u);
1413 UINT_32 endingMip
= GetMipChainInfo(pIn
->resourceType
,
1427 pOut
->epitchIsHeight
= TRUE
;
1428 pOut
->pitch
= pMipInfo
[0].pitch
;
1429 pOut
->height
= pMipInfo
[0].height
;
1430 pOut
->numSlices
= pMipInfo
[0].depth
;
1431 pOut
->firstMipInTail
= TRUE
;
1435 UINT_32 mip0WidthInBlk
= pOut
->pitch
/ pOut
->blockWidth
;
1436 UINT_32 mip0HeightInBlk
= pOut
->height
/ pOut
->blockHeight
;
1438 AddrMajorMode majorMode
= GetMajorMode(pIn
->resourceType
,
1442 pOut
->numSlices
/ pOut
->blockSlices
);
1443 if (majorMode
== ADDR_MAJOR_Y
)
1445 UINT_32 mip1WidthInBlk
= RoundHalf(mip0WidthInBlk
);
1447 if ((mip1WidthInBlk
== 1) && (endingMip
> 2))
1452 pOut
->mipChainPitch
+= (mip1WidthInBlk
* pOut
->blockWidth
);
1454 pOut
->epitchIsHeight
= FALSE
;
1458 UINT_32 mip1HeightInBlk
= RoundHalf(mip0HeightInBlk
);
1460 if ((mip1HeightInBlk
== 1) && (endingMip
> 2))
1465 pOut
->mipChainHeight
+= (mip1HeightInBlk
* pOut
->blockHeight
);
1467 pOut
->epitchIsHeight
= TRUE
;
1471 else if (pOut
->pMipInfo
!= NULL
)
1473 pOut
->pMipInfo
[0].pitch
= pOut
->pitch
;
1474 pOut
->pMipInfo
[0].height
= pOut
->height
;
1475 pOut
->pMipInfo
[0].depth
= IsTex3d(pIn
->resourceType
)? pOut
->numSlices
: 1;
1476 pOut
->pMipInfo
[0].offset
= 0;
1479 pOut
->sliceSize
= pOut
->mipChainPitch
*pOut
->mipChainHeight
*
1480 (pIn
->bpp
>> 3) * pIn
->numFrags
;
1481 pOut
->surfSize
= pOut
->sliceSize
* pOut
->mipChainSlice
;
1482 pOut
->baseAlign
= ComputeSurfaceBaseAlign(pIn
->swizzleMode
);
1490 ****************************************************************************************************
1491 * Lib::ComputeSurfaceAddrFromCoordLinear
1494 * Internal function to calculate address from coord for linear swizzle surface
1498 ****************************************************************************************************
1500 ADDR_E_RETURNCODE
Lib::ComputeSurfaceAddrFromCoordLinear(
1501 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1502 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1505 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1506 BOOL_32 valid
= (pIn
->numSamples
<= 1) && (pIn
->numFrags
<= 1) && (pIn
->pipeBankXor
== 0);
1510 if (IsTex1d(pIn
->resourceType
))
1512 valid
= (pIn
->y
== 0);
1518 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {0};
1519 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut
= {0};
1520 localIn
.bpp
= pIn
->bpp
;
1521 localIn
.width
= Max(pIn
->unalignedWidth
, 1u);
1522 localIn
.height
= Max(pIn
->unalignedHeight
, 1u);
1523 localIn
.numSlices
= Max(pIn
->numSlices
, 1u);
1524 localIn
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
1525 localIn
.resourceType
= pIn
->resourceType
;
1526 if (localIn
.numMipLevels
<= 1)
1528 localIn
.pitchInElement
= pIn
->pitchInElement
;
1530 returnCode
= ComputeSurfaceInfoLinear(&localIn
, &localOut
);
1532 if (returnCode
== ADDR_OK
)
1534 UINT_32 elementBytes
= pIn
->bpp
>> 3;
1535 UINT_64 sliceOffsetInSurf
= static_cast<UINT_64
>(pIn
->slice
) * localOut
.sliceSize
;
1536 UINT_64 mipOffsetInSlice
= 0;
1537 UINT_64 offsetInMip
= 0;
1539 if (IsTex1d(pIn
->resourceType
))
1541 offsetInMip
= static_cast<UINT_64
>(pIn
->x
) * elementBytes
;
1542 mipOffsetInSlice
= static_cast<UINT_64
>(pIn
->mipId
) * localOut
.pitch
* elementBytes
;
1546 UINT_64 mipStartHeight
= SumGeo(localIn
.height
, pIn
->mipId
);
1547 mipOffsetInSlice
= static_cast<UINT_64
>(mipStartHeight
) * localOut
.pitch
* elementBytes
;
1548 offsetInMip
= (pIn
->y
* localOut
.pitch
+ pIn
->x
) * elementBytes
;
1551 pOut
->addr
= sliceOffsetInSurf
+ mipOffsetInSlice
+ offsetInMip
;
1552 pOut
->bitPosition
= 0;
1562 returnCode
= ADDR_INVALIDPARAMS
;
1569 ****************************************************************************************************
1570 * Lib::ComputeSurfaceAddrFromCoordTiled
1573 * Internal function to calculate address from coord for tiled swizzle surface
1577 ****************************************************************************************************
1579 ADDR_E_RETURNCODE
Lib::ComputeSurfaceAddrFromCoordTiled(
1580 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
1581 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
1584 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {0};
1585 localIn
.swizzleMode
= pIn
->swizzleMode
;
1586 localIn
.flags
= pIn
->flags
;
1587 localIn
.resourceType
= pIn
->resourceType
;
1588 localIn
.bpp
= pIn
->bpp
;
1589 localIn
.width
= Max(pIn
->unalignedWidth
, 1u);
1590 localIn
.height
= Max(pIn
->unalignedHeight
, 1u);
1591 localIn
.numSlices
= Max(pIn
->numSlices
, 1u);
1592 localIn
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
1593 if (localIn
.numMipLevels
<= 1)
1595 localIn
.pitchInElement
= pIn
->pitchInElement
;
1598 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut
= {0};
1599 ADDR_E_RETURNCODE returnCode
= ComputeSurfaceInfoTiled(&localIn
, &localOut
);
1601 BOOL_32 valid
= (returnCode
== ADDR_OK
) &&
1602 (IsThin(pIn
->resourceType
, pIn
->swizzleMode
) ||
1603 IsThick(pIn
->resourceType
, pIn
->swizzleMode
)) &&
1604 ((pIn
->pipeBankXor
== 0) || (IsXor(pIn
->swizzleMode
)));
1608 Dim3d mipStartPos
= {0};
1609 UINT_32 mipTailOffset
= 0;
1611 if (pIn
->numMipLevels
> 1)
1613 // Mip-map chain cannot be MSAA surface
1614 ADDR_ASSERT((pIn
->numSamples
<= 1) && (pIn
->numFrags
<= 1));
1616 mipStartPos
= GetMipStartPos(pIn
->resourceType
,
1621 localOut
.blockWidth
,
1622 localOut
.blockHeight
,
1623 localOut
.blockSlices
,
1628 UINT_32 interleaveOffset
= 0;
1629 UINT_32 pipeBits
= 0;
1630 UINT_32 pipeXor
= 0;
1631 UINT_32 bankBits
= 0;
1632 UINT_32 bankXor
= 0;
1634 if (IsThin(pIn
->resourceType
, pIn
->swizzleMode
))
1636 UINT_32 blockOffset
= 0;
1637 UINT_32 log2blkSize
= GetBlockSizeLog2(pIn
->swizzleMode
);
1638 UINT_32 log2ElementBytes
= Log2(pIn
->bpp
>> 3);
1640 if (IsZOrderSwizzle(pIn
->swizzleMode
))
1642 // Morton generation
1643 if ((log2ElementBytes
== 0) || (log2ElementBytes
== 2))
1645 UINT_32 totalLowBits
= 6 - log2ElementBytes
;
1646 UINT_32 mortBits
= totalLowBits
/ 2;
1647 UINT_32 lowBitsValue
= MortonGen2d(pIn
->y
, pIn
->x
, mortBits
);
1648 // Are 9 bits enough?
1649 UINT_32 highBitsValue
=
1650 MortonGen2d(pIn
->x
>> mortBits
, pIn
->y
>> mortBits
, 9) << totalLowBits
;
1651 blockOffset
= lowBitsValue
| highBitsValue
;
1652 ADDR_ASSERT(blockOffset
== lowBitsValue
+ highBitsValue
);
1656 blockOffset
= MortonGen2d(pIn
->y
, pIn
->x
, 13);
1659 // Fill LSBs with sample bits
1660 if (pIn
->numSamples
> 1)
1662 blockOffset
*= pIn
->numSamples
;
1663 blockOffset
|= pIn
->sample
;
1666 // Shift according to BytesPP
1667 blockOffset
<<= log2ElementBytes
;
1671 // Micro block offset
1672 UINT_32 microBlockOffset
= ComputeSurface2DMicroBlockOffset(pIn
);
1673 blockOffset
= microBlockOffset
;
1675 // Micro block dimension
1676 ADDR_ASSERT(log2ElementBytes
< sizeof(Block256b
) / sizeof(Block256b
[0]));
1677 Dim2d microBlockDim
= Block256b
[log2ElementBytes
];
1678 // Morton generation, does 12 bit enough?
1680 MortonGen2d((pIn
->x
/ microBlockDim
.w
), (pIn
->y
/ microBlockDim
.h
), 12) << 8;
1682 // Sample bits start location
1683 UINT_32 sampleStart
= log2blkSize
- Log2(pIn
->numSamples
);
1684 // Join sample bits information to the highest Macro block bits
1685 if (IsNonPrtXor(pIn
->swizzleMode
))
1687 // Non-prt-Xor : xor highest Macro block bits with sample bits
1688 blockOffset
= blockOffset
^ (pIn
->sample
<< sampleStart
);
1692 // Non-Xor or prt-Xor: replace highest Macro block bits with sample bits
1693 // after this op, the blockOffset only contains log2 Macro block size bits
1694 blockOffset
%= (1 << sampleStart
);
1695 blockOffset
|= (pIn
->sample
<< sampleStart
);
1696 ADDR_ASSERT((blockOffset
>> log2blkSize
) == 0);
1700 if (IsXor(pIn
->swizzleMode
))
1702 // Mask off bits above Macro block bits to keep page synonyms working for prt
1703 if (IsPrt(pIn
->swizzleMode
))
1705 blockOffset
&= ((1 << log2blkSize
) - 1);
1708 // Preserve offset inside pipe interleave
1709 interleaveOffset
= blockOffset
& ((1 << m_pipeInterleaveLog2
) - 1);
1710 blockOffset
>>= m_pipeInterleaveLog2
;
1713 pipeBits
= GetPipeXorBits(log2blkSize
);
1715 pipeXor
= FoldXor2d(blockOffset
, pipeBits
);
1716 blockOffset
>>= pipeBits
;
1719 bankBits
= GetBankXorBits(log2blkSize
);
1721 bankXor
= FoldXor2d(blockOffset
, bankBits
);
1722 blockOffset
>>= bankBits
;
1724 // Put all the part back together
1725 blockOffset
<<= bankBits
;
1726 blockOffset
|= bankXor
;
1727 blockOffset
<<= pipeBits
;
1728 blockOffset
|= pipeXor
;
1729 blockOffset
<<= m_pipeInterleaveLog2
;
1730 blockOffset
|= interleaveOffset
;
1733 ADDR_ASSERT((blockOffset
| mipTailOffset
) == (blockOffset
+ mipTailOffset
));
1734 blockOffset
|= mipTailOffset
;
1736 if (IsNonPrtXor(pIn
->swizzleMode
) && (pIn
->numSamples
<= 1))
1738 // Apply slice xor if not MSAA/PRT
1739 blockOffset
^= (ReverseBitVector(pIn
->slice
, pipeBits
) << m_pipeInterleaveLog2
);
1740 blockOffset
^= (ReverseBitVector(pIn
->slice
>> pipeBits
, bankBits
) <<
1741 (m_pipeInterleaveLog2
+ pipeBits
));
1744 returnCode
= ApplyCustomerPipeBankXor(pIn
->swizzleMode
, pIn
->pipeBankXor
,
1745 bankBits
, pipeBits
, &blockOffset
);
1747 blockOffset
%= (1 << log2blkSize
);
1749 UINT_32 pitchInMacroBlock
= localOut
.mipChainPitch
/ localOut
.blockWidth
;
1750 UINT_32 paddedHeightInMacroBlock
= localOut
.mipChainHeight
/ localOut
.blockHeight
;
1751 UINT_32 sliceSizeInMacroBlock
= pitchInMacroBlock
* paddedHeightInMacroBlock
;
1752 UINT_32 macroBlockIndex
=
1753 (pIn
->slice
+ mipStartPos
.d
) * sliceSizeInMacroBlock
+
1754 ((pIn
->y
/ localOut
.blockHeight
) + mipStartPos
.h
) * pitchInMacroBlock
+
1755 ((pIn
->x
/ localOut
.blockWidth
) + mipStartPos
.w
);
1757 UINT_64 macroBlockOffset
= (static_cast<UINT_64
>(macroBlockIndex
) <<
1758 GetBlockSizeLog2(pIn
->swizzleMode
));
1760 pOut
->addr
= blockOffset
| macroBlockOffset
;
1764 UINT_32 log2blkSize
= GetBlockSizeLog2(pIn
->swizzleMode
);
1765 UINT_32 log2ElementBytes
= Log2(pIn
->bpp
>> 3);
1767 Dim3d microBlockDim
= Block1kb
[log2ElementBytes
];
1769 UINT_32 blockOffset
= MortonGen3d((pIn
->x
/ microBlockDim
.w
),
1770 (pIn
->y
/ microBlockDim
.h
),
1771 (pIn
->slice
/ microBlockDim
.d
),
1775 blockOffset
|= ComputeSurface3DMicroBlockOffset(pIn
);
1777 if (IsXor(pIn
->swizzleMode
))
1779 // Mask off bits above Macro block bits to keep page synonyms working for prt
1780 if (IsPrt(pIn
->swizzleMode
))
1782 blockOffset
&= ((1 << log2blkSize
) - 1);
1785 // Preserve offset inside pipe interleave
1786 interleaveOffset
= blockOffset
& ((1 << m_pipeInterleaveLog2
) - 1);
1787 blockOffset
>>= m_pipeInterleaveLog2
;
1790 pipeBits
= GetPipeXorBits(log2blkSize
);
1792 pipeXor
= FoldXor3d(blockOffset
, pipeBits
);
1793 blockOffset
>>= pipeBits
;
1796 bankBits
= GetBankXorBits(log2blkSize
);
1798 bankXor
= FoldXor3d(blockOffset
, bankBits
);
1799 blockOffset
>>= bankBits
;
1801 // Put all the part back together
1802 blockOffset
<<= bankBits
;
1803 blockOffset
|= bankXor
;
1804 blockOffset
<<= pipeBits
;
1805 blockOffset
|= pipeXor
;
1806 blockOffset
<<= m_pipeInterleaveLog2
;
1807 blockOffset
|= interleaveOffset
;
1810 ADDR_ASSERT((blockOffset
| mipTailOffset
) == (blockOffset
+ mipTailOffset
));
1811 blockOffset
|= mipTailOffset
;
1813 returnCode
= ApplyCustomerPipeBankXor(pIn
->swizzleMode
, pIn
->pipeBankXor
,
1814 bankBits
, pipeBits
, &blockOffset
);
1816 blockOffset
%= (1 << log2blkSize
);
1818 UINT_32 xb
= (pIn
->x
+ mipStartPos
.w
) / localOut
.blockWidth
;
1819 UINT_32 yb
= (pIn
->y
+ mipStartPos
.h
) / localOut
.blockHeight
;
1820 UINT_32 zb
= (pIn
->slice
+ mipStartPos
.d
) / localOut
.blockSlices
;
1822 UINT_32 pitchInBlock
= localOut
.mipChainPitch
/ localOut
.blockWidth
;
1823 UINT_32 sliceSizeInBlock
=
1824 (localOut
.mipChainHeight
/ localOut
.blockHeight
) * pitchInBlock
;
1825 UINT_32 blockIndex
= zb
* sliceSizeInBlock
+ yb
* pitchInBlock
+ xb
;
1827 pOut
->addr
= blockOffset
| (blockIndex
<< log2blkSize
);
1832 returnCode
= ADDR_INVALIDPARAMS
;
1839 ****************************************************************************************************
1840 * Lib::ComputeSurfaceCoordFromAddrLinear
1843 * Internal function to calculate coord from address for linear swizzle surface
1847 ****************************************************************************************************
1849 ADDR_E_RETURNCODE
Lib::ComputeSurfaceCoordFromAddrLinear(
1850 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1851 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1854 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
1856 BOOL_32 valid
= (pIn
->numSamples
<= 1) && (pIn
->numFrags
<= 1);
1860 if (IsTex1d(pIn
->resourceType
))
1862 valid
= (pIn
->unalignedHeight
== 1);
1868 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {0};
1869 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut
= {0};
1870 localIn
.bpp
= pIn
->bpp
;
1871 localIn
.width
= Max(pIn
->unalignedWidth
, 1u);
1872 localIn
.height
= Max(pIn
->unalignedHeight
, 1u);
1873 localIn
.numSlices
= Max(pIn
->numSlices
, 1u);
1874 localIn
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
1875 localIn
.resourceType
= pIn
->resourceType
;
1876 if (localIn
.numMipLevels
<= 1)
1878 localIn
.pitchInElement
= pIn
->pitchInElement
;
1880 returnCode
= ComputeSurfaceInfoLinear(&localIn
, &localOut
);
1882 if (returnCode
== ADDR_OK
)
1884 pOut
->slice
= static_cast<UINT_32
>(pIn
->addr
/ localOut
.sliceSize
);
1887 UINT_32 offsetInSlice
= static_cast<UINT_32
>(pIn
->addr
% localOut
.sliceSize
);
1888 UINT_32 elementBytes
= pIn
->bpp
>> 3;
1889 UINT_32 mipOffsetInSlice
= 0;
1890 UINT_32 mipSize
= 0;
1892 for (; mipId
< pIn
->numMipLevels
; mipId
++)
1894 if (IsTex1d(pIn
->resourceType
))
1896 mipSize
= localOut
.pitch
* elementBytes
;
1900 UINT_32 currentMipHeight
= (PowTwoAlign(localIn
.height
, (1 << mipId
))) >> mipId
;
1901 mipSize
= currentMipHeight
* localOut
.pitch
* elementBytes
;
1909 else if ((mipSize
+ mipOffsetInSlice
) > offsetInSlice
)
1915 mipOffsetInSlice
+= mipSize
;
1916 if ((mipId
== (pIn
->numMipLevels
- 1)) ||
1917 (mipOffsetInSlice
>= localOut
.sliceSize
))
1926 pOut
->mipId
= mipId
;
1928 UINT_32 elemOffsetInMip
= (offsetInSlice
- mipOffsetInSlice
) / elementBytes
;
1929 if (IsTex1d(pIn
->resourceType
))
1931 if (elemOffsetInMip
< localOut
.pitch
)
1933 pOut
->x
= elemOffsetInMip
;
1943 pOut
->y
= elemOffsetInMip
/ localOut
.pitch
;
1944 pOut
->x
= elemOffsetInMip
% localOut
.pitch
;
1947 if ((pOut
->slice
>= pIn
->numSlices
) ||
1948 (pOut
->mipId
>= pIn
->numMipLevels
) ||
1949 (pOut
->x
>= Max((pIn
->unalignedWidth
>> pOut
->mipId
), 1u)) ||
1950 (pOut
->y
>= Max((pIn
->unalignedHeight
>> pOut
->mipId
), 1u)) ||
1951 (IsTex3d(pIn
->resourceType
) &&
1952 (FALSE
== Valid3DMipSliceIdConstraint(pIn
->numSlices
,
1968 returnCode
= ADDR_INVALIDPARAMS
;
1975 ****************************************************************************************************
1976 * Lib::ComputeSurfaceCoordFromAddrTiled
1979 * Internal function to calculate coord from address for tiled swizzle surface
1983 ****************************************************************************************************
1985 ADDR_E_RETURNCODE
Lib::ComputeSurfaceCoordFromAddrTiled(
1986 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
1987 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
1990 ADDR_E_RETURNCODE returnCode
= ADDR_NOTIMPLEMENTED
;
1992 ADDR_NOT_IMPLEMENTED();
1998 ****************************************************************************************************
1999 * Lib::ComputeSurfaceInfoLinear
2002 * Internal function to calculate padding for linear swizzle 2D/3D surface
2006 ****************************************************************************************************
2008 ADDR_E_RETURNCODE
Lib::ComputeSurfaceLinearPadding(
2009 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input srtucture
2010 UINT_32
* pMipmap0PaddedWidth
, ///< [out] padded width in element
2011 UINT_32
* pSlice0PaddedHeight
, ///< [out] padded height for HW
2012 ADDR2_MIP_INFO
* pMipInfo
///< [out] per mip information
2015 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2017 UINT_32 elementBytes
= pIn
->bpp
>> 3;
2018 UINT_32 widthAlignInElement
= 0;
2020 if (pIn
->swizzleMode
== ADDR_SW_LINEAR_GENERAL
)
2022 ADDR_ASSERT(pIn
->numMipLevels
<= 1);
2023 ADDR_ASSERT(pIn
->numSlices
<= 1);
2024 widthAlignInElement
= 1;
2028 widthAlignInElement
= (256 / elementBytes
);
2031 UINT_32 mipChainWidth
= PowTwoAlign(pIn
->width
, widthAlignInElement
);
2032 UINT_32 slice0PaddedHeight
= pIn
->height
;
2034 returnCode
= ApplyCustomizedPitchHeight(pIn
, elementBytes
, widthAlignInElement
,
2035 &mipChainWidth
, &slice0PaddedHeight
);
2037 if (returnCode
== ADDR_OK
)
2039 UINT_32 mipChainHeight
= 0;
2040 UINT_32 mipHeight
= pIn
->height
;
2042 for (UINT_32 i
= 0; i
< pIn
->numMipLevels
; i
++)
2044 if (pMipInfo
!= NULL
)
2046 pMipInfo
[i
].offset
= mipChainWidth
* mipChainHeight
* elementBytes
;
2047 pMipInfo
[i
].pitch
= mipChainWidth
;
2048 pMipInfo
[i
].height
= mipHeight
;
2049 pMipInfo
[i
].depth
= 1;
2052 mipChainHeight
+= mipHeight
;
2053 mipHeight
= RoundHalf(mipHeight
);
2054 mipHeight
= Max(mipHeight
, 1u);
2057 *pMipmap0PaddedWidth
= mipChainWidth
;
2058 *pSlice0PaddedHeight
= (pIn
->numMipLevels
> 1) ? mipChainHeight
: slice0PaddedHeight
;
2065 ****************************************************************************************************
2066 * Lib::ComputeBlockDimensionForSurf
2069 * Internal function to get block width/height/depth in element from surface input params.
2073 ****************************************************************************************************
2075 ADDR_E_RETURNCODE
Lib::ComputeBlockDimensionForSurf(
2079 AddrResourceType resourceType
,
2080 AddrSwizzleMode swizzleMode
) const
2082 return ComputeBlockDimensionForSurf(&pDim
->w
, &pDim
->h
, &pDim
->d
, bpp
,
2083 numSamples
, resourceType
, swizzleMode
);
2087 ****************************************************************************************************
2088 * Lib::ComputeBlockDimensionForSurf
2091 * Internal function to get block width/height/depth in element from surface input params.
2095 ****************************************************************************************************
2097 ADDR_E_RETURNCODE
Lib::ComputeBlockDimensionForSurf(
2103 AddrResourceType resourceType
,
2104 AddrSwizzleMode swizzleMode
) const
2106 ADDR_E_RETURNCODE returnCode
= ComputeBlockDimension(pWidth
,
2113 if ((returnCode
== ADDR_OK
) && (numSamples
> 1) && IsThin(resourceType
, swizzleMode
))
2115 UINT_32 log2blkSize
= GetBlockSizeLog2(swizzleMode
);
2116 UINT_32 sample
= numSamples
;
2117 UINT_32 log2sample
= Log2(sample
);
2119 *pWidth
>>= (log2sample
/ 2);
2120 *pHeight
>>= (log2sample
/ 2);
2122 if ((log2blkSize
% 2) == 0)
2124 *pWidth
>>= (sample
% 2);
2128 *pHeight
>>= (sample
% 2);
2136 ****************************************************************************************************
2137 * Lib::ComputeBlockDimension
2140 * Internal function to get block width/height/depth in element without considering MSAA case
2144 ****************************************************************************************************
2146 ADDR_E_RETURNCODE
Lib::ComputeBlockDimension(
2151 AddrResourceType resourceType
,
2152 AddrSwizzleMode swizzleMode
) const
2154 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2156 UINT_32 eleBytes
= bpp
>> 3;
2157 UINT_32 microBlockSizeTableIndex
= Log2(eleBytes
);
2158 UINT_32 log2blkSize
= GetBlockSizeLog2(swizzleMode
);
2160 if (IsThin(resourceType
, swizzleMode
))
2167 UINT_32 log2blkSizeIn256B
= log2blkSize
- 8;
2168 UINT_32 widthAmp
= log2blkSizeIn256B
/ 2;
2169 UINT_32 heightAmp
= log2blkSizeIn256B
- widthAmp
;
2171 ADDR_ASSERT(microBlockSizeTableIndex
< sizeof(Block256b
) / sizeof(Block256b
[0]));
2173 *pWidth
= (Block256b
[microBlockSizeTableIndex
].w
<< widthAmp
);
2174 *pHeight
= (Block256b
[microBlockSizeTableIndex
].h
<< heightAmp
);
2176 else if (IsThick(resourceType
, swizzleMode
))
2178 UINT_32 log2blkSizeIn1KB
= log2blkSize
- 10;
2179 UINT_32 averageAmp
= log2blkSizeIn1KB
/ 3;
2180 UINT_32 restAmp
= log2blkSizeIn1KB
% 3;
2182 ADDR_ASSERT(microBlockSizeTableIndex
< sizeof(Block1kb
) / sizeof(Block1kb
[0]));
2184 *pWidth
= Block1kb
[microBlockSizeTableIndex
].w
<< averageAmp
;
2185 *pHeight
= Block1kb
[microBlockSizeTableIndex
].h
<< (averageAmp
+ (restAmp
/ 2));
2186 *pDepth
= Block1kb
[microBlockSizeTableIndex
].d
<< (averageAmp
+ ((restAmp
!= 0) ? 1 : 0));
2190 ADDR_ASSERT_ALWAYS();
2191 returnCode
= ADDR_INVALIDPARAMS
;
2198 ****************************************************************************************************
2199 * Lib::GetMipChainInfo
2202 * Internal function to get out information about mip chain
2205 * Smaller value between Id of first mip fitted in mip tail and max Id of mip being created
2206 ****************************************************************************************************
2208 UINT_32
Lib::GetMipChainInfo(
2209 AddrResourceType resourceType
,
2210 AddrSwizzleMode swizzleMode
,
2216 UINT_32 blockHeight
,
2218 UINT_32 numMipLevel
,
2219 ADDR2_MIP_INFO
* pMipInfo
) const
2221 const Dim3d tailMaxDim
=
2222 GetMipTailDim(resourceType
, swizzleMode
, blockWidth
, blockHeight
, blockDepth
);
2224 UINT_32 mipPitch
= mip0Width
;
2225 UINT_32 mipHeight
= mip0Height
;
2226 UINT_32 mipDepth
= IsTex3d(resourceType
) ? mip0Depth
: 1;
2228 UINT_32 endingMip
= numMipLevel
- 1;
2229 BOOL_32 inTail
= FALSE
;
2230 BOOL_32 finalDim
= FALSE
;
2232 BOOL_32 is3dThick
= IsThick(resourceType
, swizzleMode
);
2233 BOOL_32 is3dThin
= IsTex3d(resourceType
) && SwizzleModeTable
[swizzleMode
].isDisp
;
2235 for (UINT_32 mipId
= 0; mipId
< numMipLevel
; mipId
++)
2239 if (finalDim
== FALSE
)
2245 mipSize
= mipPitch
* mipHeight
* mipDepth
* (bpp
>> 3);
2249 mipSize
= mipPitch
* mipHeight
* (bpp
>> 3);
2254 UINT_32 index
= Log2(bpp
>> 3);
2258 mipPitch
= CompressBlock3dZ
[index
].w
;
2259 mipHeight
= CompressBlock3dZ
[index
].h
;
2260 mipDepth
= CompressBlock3dZ
[index
].d
;
2264 mipPitch
= CompressBlock2d
[index
].w
;
2265 mipHeight
= CompressBlock2d
[index
].h
;
2274 inTail
= IsInMipTail(resourceType
, swizzleMode
, tailMaxDim
,
2275 mipPitch
, mipHeight
, mipDepth
);
2281 mipPitch
= tailMaxDim
.w
;
2282 mipHeight
= tailMaxDim
.h
;
2286 mipDepth
= tailMaxDim
.d
;
2291 mipPitch
= PowTwoAlign(mipPitch
, blockWidth
);
2292 mipHeight
= PowTwoAlign(mipHeight
, blockHeight
);
2296 mipDepth
= PowTwoAlign(mipDepth
, blockDepth
);
2301 pMipInfo
[mipId
].pitch
= mipPitch
;
2302 pMipInfo
[mipId
].height
= mipHeight
;
2303 pMipInfo
[mipId
].depth
= mipDepth
;
2304 pMipInfo
[mipId
].offset
= offset
;
2305 offset
+= (mipPitch
* mipHeight
* mipDepth
* (bpp
>> 3));
2311 mipDepth
= Max(mipDepth
>> 1, 1u);
2316 mipPitch
= Max(mipPitch
>> 1, 1u);
2317 mipHeight
= Max(mipHeight
>> 1, 1u);
2319 if (is3dThick
|| is3dThin
)
2321 mipDepth
= Max(mipDepth
>> 1, 1u);
2330 ****************************************************************************************************
2331 * Lib::GetMipStartPos
2334 * Internal function to get out information about mip logical start position
2337 * logical start position in macro block width/heith/depth of one mip level within one slice
2338 ****************************************************************************************************
2340 Dim3d
Lib::GetMipStartPos(
2341 AddrResourceType resourceType
,
2342 AddrSwizzleMode swizzleMode
,
2347 UINT_32 blockHeight
,
2350 UINT_32
* pMipTailOffset
) const
2352 Dim3d mipStartPos
= {0};
2354 const Dim3d tailMaxDim
=
2355 GetMipTailDim(resourceType
, swizzleMode
, blockWidth
, blockHeight
, blockDepth
);
2357 // Report mip in tail if Mip0 is already in mip tail
2358 BOOL_32 inMipTail
= IsInMipTail(resourceType
, swizzleMode
, tailMaxDim
, width
, height
, depth
);
2360 UINT_32 log2blkSize
= GetBlockSizeLog2(swizzleMode
);
2362 if (inMipTail
== FALSE
)
2364 // Mip 0 dimension, unit in block
2365 UINT_32 mipWidthInBlk
= width
/ blockWidth
;
2366 UINT_32 mipHeightInBlk
= height
/ blockHeight
;
2367 UINT_32 mipDepthInBlk
= depth
/ blockDepth
;
2368 AddrMajorMode majorMode
= GetMajorMode(resourceType
,
2374 UINT_32 endingMip
= mipId
+ 1;
2376 for (UINT_32 i
= 1; i
<= mipId
; i
++)
2378 if ((i
== 1) || (i
== 3))
2380 if (majorMode
== ADDR_MAJOR_Y
)
2382 mipStartPos
.w
+= mipWidthInBlk
;
2386 mipStartPos
.h
+= mipHeightInBlk
;
2391 if (majorMode
== ADDR_MAJOR_X
)
2393 mipStartPos
.w
+= mipWidthInBlk
;
2395 else if (majorMode
== ADDR_MAJOR_Y
)
2397 mipStartPos
.h
+= mipHeightInBlk
;
2401 mipStartPos
.d
+= mipDepthInBlk
;
2405 BOOL_32 inTail
= FALSE
;
2407 if (IsThick(resourceType
, swizzleMode
))
2409 UINT_32 dim
= log2blkSize
% 3;
2414 (mipWidthInBlk
<= 2) && (mipHeightInBlk
== 1) && (mipDepthInBlk
<= 2);
2419 (mipWidthInBlk
== 1) && (mipHeightInBlk
<= 2) && (mipDepthInBlk
<= 2);
2424 (mipWidthInBlk
<= 2) && (mipHeightInBlk
<= 2) && (mipDepthInBlk
== 1);
2429 if (log2blkSize
& 1)
2431 inTail
= (mipWidthInBlk
<= 2) && (mipHeightInBlk
== 1);
2435 inTail
= (mipWidthInBlk
== 1) && (mipHeightInBlk
<= 2);
2445 mipWidthInBlk
= RoundHalf(mipWidthInBlk
);
2446 mipHeightInBlk
= RoundHalf(mipHeightInBlk
);
2447 mipDepthInBlk
= RoundHalf(mipDepthInBlk
);
2450 if (mipId
>= endingMip
)
2453 UINT_32 index
= mipId
- endingMip
+ MaxMacroBits
- log2blkSize
;
2454 ADDR_ASSERT(index
< sizeof(MipTailOffset
) / sizeof(UINT_32
));
2455 *pMipTailOffset
= MipTailOffset
[index
] << 8;
2460 UINT_32 index
= mipId
+ MaxMacroBits
- log2blkSize
;
2461 ADDR_ASSERT(index
< sizeof(MipTailOffset
) / sizeof(UINT_32
));
2462 *pMipTailOffset
= MipTailOffset
[index
] << 8;
2469 ****************************************************************************************************
2470 * Lib::GetMipTailDim
2473 * Internal function to get out max dimension of first level in mip tail
2476 * Max Width/Height/Depth value of the first mip fitted in mip tail
2477 ****************************************************************************************************
2479 Dim3d
Lib::GetMipTailDim(
2480 AddrResourceType resourceType
,
2481 AddrSwizzleMode swizzleMode
,
2483 UINT_32 blockHeight
,
2484 UINT_32 blockDepth
) const
2486 Dim3d out
= {blockWidth
, blockHeight
, blockDepth
};
2487 UINT_32 log2blkSize
= GetBlockSizeLog2(swizzleMode
);
2489 if (IsThick(resourceType
, swizzleMode
))
2491 UINT_32 dim
= log2blkSize
% 3;
2508 if (log2blkSize
& 1)
2522 ****************************************************************************************************
2523 * Lib::ComputeSurface2DMicroBlockOffset
2526 * Internal function to calculate micro block (256B) offset from coord for 2D resource
2529 * micro block (256B) offset for 2D resource
2530 ****************************************************************************************************
2532 UINT_32
Lib::ComputeSurface2DMicroBlockOffset(
2533 const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
) const
2535 ADDR_ASSERT(IsThin(pIn
->resourceType
, pIn
->swizzleMode
));
2537 UINT_32 log2ElementBytes
= Log2(pIn
->bpp
>> 3);
2538 UINT_32 microBlockOffset
= 0;
2539 if (IsStandardSwizzle(pIn
->resourceType
, pIn
->swizzleMode
))
2541 UINT_32 xBits
= pIn
->x
<< log2ElementBytes
;
2542 microBlockOffset
= (xBits
& 0xf) | ((pIn
->y
& 0x3) << 4);
2543 if (log2ElementBytes
< 3)
2545 microBlockOffset
|= (pIn
->y
& 0x4) << 4;
2546 if (log2ElementBytes
== 0)
2548 microBlockOffset
|= (pIn
->y
& 0x8) << 4;
2552 microBlockOffset
|= (xBits
& 0x10) << 3;
2557 microBlockOffset
|= (xBits
& 0x30) << 2;
2560 else if (IsDisplaySwizzle(pIn
->resourceType
, pIn
->swizzleMode
))
2562 if (log2ElementBytes
== 4)
2564 microBlockOffset
= (GetBit(pIn
->x
, 0) << 4) |
2565 (GetBit(pIn
->y
, 0) << 5) |
2566 (GetBit(pIn
->x
, 1) << 6) |
2567 (GetBit(pIn
->y
, 1) << 7);
2571 microBlockOffset
= GetBits(pIn
->x
, 0, 3, log2ElementBytes
) |
2572 GetBits(pIn
->y
, 1, 2, 3 + log2ElementBytes
) |
2573 GetBits(pIn
->x
, 3, 1, 5 + log2ElementBytes
) |
2574 GetBits(pIn
->y
, 3, 1, 6 + log2ElementBytes
);
2575 microBlockOffset
= GetBits(microBlockOffset
, 0, 4, 0) |
2576 (GetBit(pIn
->y
, 0) << 4) |
2577 GetBits(microBlockOffset
, 4, 3, 5);
2580 else if (IsRotateSwizzle(pIn
->swizzleMode
))
2582 microBlockOffset
= GetBits(pIn
->y
, 0, 3, log2ElementBytes
) |
2583 GetBits(pIn
->x
, 1, 2, 3 + log2ElementBytes
) |
2584 GetBits(pIn
->x
, 3, 1, 5 + log2ElementBytes
) |
2585 GetBits(pIn
->y
, 3, 1, 6 + log2ElementBytes
);
2586 microBlockOffset
= GetBits(microBlockOffset
, 0, 4, 0) |
2587 (GetBit(pIn
->x
, 0) << 4) |
2588 GetBits(microBlockOffset
, 4, 3, 5);
2589 if (log2ElementBytes
== 3)
2591 microBlockOffset
= GetBits(microBlockOffset
, 0, 6, 0) |
2592 GetBits(pIn
->x
, 1, 2, 6);
2596 return microBlockOffset
;
2600 ****************************************************************************************************
2601 * Lib::ComputeSurface3DMicroBlockOffset
2604 * Internal function to calculate micro block (1KB) offset from coord for 3D resource
2607 * micro block (1KB) offset for 3D resource
2608 ****************************************************************************************************
2610 UINT_32
Lib::ComputeSurface3DMicroBlockOffset(
2611 const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
) const
2613 ADDR_ASSERT(IsThick(pIn
->resourceType
, pIn
->swizzleMode
));
2615 UINT_32 log2ElementBytes
= Log2(pIn
->bpp
>> 3);
2616 UINT_32 microBlockOffset
= 0;
2617 if (IsStandardSwizzle(pIn
->resourceType
, pIn
->swizzleMode
))
2619 if (log2ElementBytes
== 0)
2621 microBlockOffset
= ((pIn
->slice
& 4) >> 2) | ((pIn
->y
& 4) >> 1);
2623 else if (log2ElementBytes
== 1)
2625 microBlockOffset
= ((pIn
->slice
& 4) >> 2) | ((pIn
->y
& 4) >> 1);
2627 else if (log2ElementBytes
== 2)
2629 microBlockOffset
= ((pIn
->y
& 4) >> 2) | ((pIn
->x
& 4) >> 1);
2631 else if (log2ElementBytes
== 3)
2633 microBlockOffset
= (pIn
->x
& 6) >> 1;
2637 microBlockOffset
= pIn
->x
& 3;
2640 microBlockOffset
<<= 8;
2642 UINT_32 xBits
= pIn
->x
<< log2ElementBytes
;
2643 microBlockOffset
|= (xBits
& 0xf) | ((pIn
->y
& 0x3) << 4) | ((pIn
->slice
& 0x3) << 6);
2645 else if (IsZOrderSwizzle(pIn
->swizzleMode
))
2649 if (log2ElementBytes
== 0)
2652 (pIn
->x
& 1) | ((pIn
->y
& 1) << 1) | ((pIn
->x
& 2) << 1) | ((pIn
->y
& 2) << 2);
2653 microBlockOffset
= microBlockOffset
| ((pIn
->slice
& 3) << 4) | ((pIn
->x
& 4) << 4);
2657 zh
= pIn
->slice
>> 2;
2659 else if (log2ElementBytes
== 1)
2662 (pIn
->x
& 1) | ((pIn
->y
& 1) << 1) | ((pIn
->x
& 2) << 1) | ((pIn
->y
& 2) << 2);
2663 microBlockOffset
= (microBlockOffset
<< 1) | ((pIn
->slice
& 3) << 5);
2667 zh
= pIn
->slice
>> 2;
2669 else if (log2ElementBytes
== 2)
2672 (pIn
->x
& 1) | ((pIn
->y
& 1) << 1) | ((pIn
->x
& 2) << 1) | ((pIn
->slice
& 1) << 3);
2673 microBlockOffset
= (microBlockOffset
<< 2) | ((pIn
->y
& 2) << 5);
2677 zh
= pIn
->slice
>> 1;
2679 else if (log2ElementBytes
== 3)
2682 (pIn
->x
& 1) | ((pIn
->y
& 1) << 1) | ((pIn
->slice
& 1) << 2) | ((pIn
->x
& 2) << 2);
2683 microBlockOffset
<<= 3;
2687 zh
= pIn
->slice
>> 1;
2692 (((pIn
->x
& 1) | ((pIn
->y
& 1) << 1) | ((pIn
->slice
& 1) << 2)) << 4);
2696 zh
= pIn
->slice
>> 1;
2699 microBlockOffset
|= ((MortonGen3d(xh
, yh
, zh
, 1) << 7) & 0x380);
2702 return microBlockOffset
;
2706 ****************************************************************************************************
2707 * Lib::GetPipeXorBits
2710 * Internal function to get bits number for pipe/se xor operation
2714 ****************************************************************************************************
2716 UINT_32
Lib::GetPipeXorBits(
2717 UINT_32 macroBlockBits
) const
2719 ADDR_ASSERT(macroBlockBits
>= m_pipeInterleaveLog2
);
2721 // Total available xor bits
2722 UINT_32 xorBits
= macroBlockBits
- m_pipeInterleaveLog2
;
2725 UINT_32 pipeBits
= Min(xorBits
, m_pipesLog2
+ m_seLog2
);
2731 ****************************************************************************************************
2732 * Lib::GetBankXorBits
2735 * Internal function to get bits number for pipe/se xor operation
2739 ****************************************************************************************************
2741 UINT_32
Lib::GetBankXorBits(
2742 UINT_32 macroBlockBits
) const
2744 UINT_32 pipeBits
= GetPipeXorBits(macroBlockBits
);
2747 UINT_32 bankBits
= Min(macroBlockBits
- pipeBits
- m_pipeInterleaveLog2
, m_banksLog2
);
2753 ****************************************************************************************************
2754 * Lib::Addr2GetPreferredSurfaceSetting
2757 * Internal function to get suggested surface information for cliet to use
2761 ****************************************************************************************************
2763 ADDR_E_RETURNCODE
Lib::Addr2GetPreferredSurfaceSetting(
2764 const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT
* pIn
,
2765 ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT
* pOut
) const
2767 // Macro define resource block type
2770 AddrBlockMicro
= 0, // Resource uses 256B block
2771 AddrBlock4KB
= 1, // Resource uses 4KB block
2772 AddrBlock64KB
= 2, // Resource uses 64KB block
2773 AddrBlockVar
= 3, // Resource uses var blcok
2774 AddrBlockLinear
= 4, // Resource uses linear swizzle mode
2776 AddrBlockMaxTiledType
= AddrBlock64KB
+ 1,
2781 AddrBlockSetMicro
= 1 << AddrBlockMicro
,
2782 AddrBlockSetMacro4KB
= 1 << AddrBlock4KB
,
2783 AddrBlockSetMacro64KB
= 1 << AddrBlock64KB
,
2784 AddrBlockSetVar
= 1 << AddrBlockVar
,
2785 AddrBlockSetLinear
= 1 << AddrBlockLinear
,
2787 AddrBlockSetMacro
= AddrBlockSetMacro4KB
| AddrBlockSetMacro64KB
,
2790 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2791 ElemLib
* pElemLib
= GetElemLib();
2793 // Set format to INVALID will skip this conversion
2794 UINT_32 expandX
= 1;
2795 UINT_32 expandY
= 1;
2796 UINT_32 bpp
= pIn
->bpp
;
2797 if (pIn
->format
!= ADDR_FMT_INVALID
)
2799 // Don't care for this case
2800 ElemMode elemMode
= ADDR_UNCOMPRESSED
;
2802 // Get compression/expansion factors and element mode which indicates compression/expansion
2803 bpp
= pElemLib
->GetBitsPerPixel(pIn
->format
,
2809 UINT_32 numSamples
= Max(pIn
->numSamples
, 1u);
2810 UINT_32 numFrags
= (pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
;
2811 UINT_32 width
= Max(pIn
->width
/ expandX
, 1u);
2812 UINT_32 height
= Max(pIn
->height
/ expandY
, 1u);
2813 UINT_32 slice
= Max(pIn
->numSlices
, 1u);
2814 UINT_32 numMipLevels
= Max(pIn
->numMipLevels
, 1u);
2816 if (pIn
->flags
.fmask
)
2818 bpp
= GetFmaskBpp(numSamples
, numFrags
);
2821 pOut
->resourceType
= ADDR_RSRC_TEX_2D
;
2825 // The output may get changed for volume(3D) texture resource in future
2826 pOut
->resourceType
= pIn
->resourceType
;
2829 if (IsTex1d(pOut
->resourceType
))
2831 pOut
->swizzleMode
= ADDR_SW_LINEAR
;
2832 pOut
->validBlockSet
.value
= AddrBlockSetLinear
;
2833 pOut
->canXor
= FALSE
;
2837 ADDR2_BLOCK_SET blockSet
;
2842 BOOL_32 tryPrtXor
= pIn
->flags
.prt
;
2844 // Filter out improper swType and blockSet by HW restriction
2845 if (pIn
->flags
.fmask
|| pIn
->flags
.depth
|| pIn
->flags
.stencil
)
2847 ADDR_ASSERT(IsTex2d(pOut
->resourceType
));
2848 blockSet
.value
= AddrBlockSetMacro
;
2851 else if (pElemLib
->IsBlockCompressed(pIn
->format
))
2853 // block compressed formats (BCx, ASTC, ETC2) must be either S or D modes. Not sure
2854 // under what circumstances "_D" would be appropriate as these formats are not
2856 blockSet
.value
= AddrBlockSetMacro
;
2859 else if (IsTex3d(pOut
->resourceType
))
2861 blockSet
.value
= AddrBlockSetLinear
| AddrBlockSetMacro
;
2862 swType
= (slice
>= 8) ? ADDR_SW_Z
: ADDR_SW_S
;
2864 else if (numMipLevels
> 1)
2866 ADDR_ASSERT(numFrags
== 1);
2867 blockSet
.value
= AddrBlockSetLinear
| AddrBlockSetMacro
;
2868 swType
= pIn
->flags
.display
? ADDR_SW_D
: ADDR_SW_S
;
2870 else if ((numFrags
> 1) || (numSamples
> 1))
2872 ADDR_ASSERT(IsTex2d(pOut
->resourceType
));
2873 blockSet
.value
= AddrBlockSetMacro
;
2874 swType
= pIn
->flags
.display
? ADDR_SW_D
: ADDR_SW_S
;
2878 ADDR_ASSERT(IsTex2d(pOut
->resourceType
));
2879 blockSet
.value
= AddrBlockSetLinear
| AddrBlockSetMicro
| AddrBlockSetMacro
;
2880 if (pIn
->flags
.rotated
|| pIn
->flags
.display
)
2882 swType
= pIn
->flags
.rotated
? ADDR_SW_R
: ADDR_SW_D
;
2888 blockSet
.micro
= FALSE
;
2891 // DCE12 does not support display surface to be _T swizzle mode
2896 ADDR_NOT_IMPLEMENTED();
2899 else if (pIn
->flags
.overlay
)
2909 if ((numFrags
> 1) &&
2910 (GetBlockSize(ADDR_SW_4KB
) < (m_pipeInterleaveBytes
* numFrags
)))
2912 // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
2913 blockSet
.macro4KB
= FALSE
;
2918 blockSet
.value
&= AddrBlock64KB
;
2921 // Apply customized forbidden setting
2922 blockSet
.value
&= ~pIn
->forbiddenBlock
.value
;
2924 if (pIn
->maxAlign
> 0)
2926 if (pIn
->maxAlign
< GetBlockSize(ADDR_SW_64KB
))
2928 blockSet
.macro64KB
= FALSE
;
2931 if (pIn
->maxAlign
< GetBlockSize(ADDR_SW_4KB
))
2933 blockSet
.macro4KB
= FALSE
;
2936 if (pIn
->maxAlign
< GetBlockSize(ADDR_SW_256B
))
2938 blockSet
.micro
= FALSE
;
2942 Dim3d blkDim
[AddrBlockMaxTiledType
] = {{0}, {0}, {0}};
2943 Dim3d padDim
[AddrBlockMaxTiledType
] = {{0}, {0}, {0}};
2944 UINT_64 padSize
[AddrBlockMaxTiledType
] = {0};
2948 returnCode
= ComputeBlockDimensionForSurf(&blkDim
[AddrBlockMicro
],
2954 if (returnCode
== ADDR_OK
)
2956 if ((blkDim
[AddrBlockMicro
].w
>= width
) && (blkDim
[AddrBlockMicro
].h
>= height
))
2958 // If one 256B block can contain the surface, don't bother bigger block type
2959 blockSet
.macro4KB
= FALSE
;
2960 blockSet
.macro64KB
= FALSE
;
2961 blockSet
.var
= FALSE
;
2964 padSize
[AddrBlockMicro
] = ComputePadSize(&blkDim
[AddrBlockMicro
], width
, height
,
2965 slice
, &padDim
[AddrBlockMicro
]);
2969 if ((returnCode
== ADDR_OK
) && (blockSet
.macro4KB
))
2971 returnCode
= ComputeBlockDimensionForSurf(&blkDim
[AddrBlock4KB
],
2977 if (returnCode
== ADDR_OK
)
2979 padSize
[AddrBlock4KB
] = ComputePadSize(&blkDim
[AddrBlock4KB
], width
, height
,
2980 slice
, &padDim
[AddrBlock4KB
]);
2982 ADDR_ASSERT(padSize
[AddrBlock4KB
] >= padSize
[AddrBlockMicro
]);
2986 if ((returnCode
== ADDR_OK
) && (blockSet
.macro64KB
))
2988 returnCode
= ComputeBlockDimensionForSurf(&blkDim
[AddrBlock64KB
],
2994 if (returnCode
== ADDR_OK
)
2996 padSize
[AddrBlock64KB
] = ComputePadSize(&blkDim
[AddrBlock64KB
], width
, height
,
2997 slice
, &padDim
[AddrBlock64KB
]);
2999 ADDR_ASSERT(padSize
[AddrBlock64KB
] >= padSize
[AddrBlock4KB
]);
3000 ADDR_ASSERT(padSize
[AddrBlock64KB
] >= padSize
[AddrBlockMicro
]);
3002 if ((padSize
[AddrBlock64KB
] >= static_cast<UINT_64
>(width
) * height
* slice
* 2) &&
3003 ((blockSet
.value
& ~AddrBlockSetMacro64KB
) != 0))
3005 // If 64KB block waste more than half memory on padding, filter it out from
3006 // candidate list when it is not the only choice left
3007 blockSet
.macro64KB
= FALSE
;
3012 if (returnCode
== ADDR_OK
)
3014 // Use minimum block type which meets all conditions above if flag minimizeAlign was set
3015 if (pIn
->flags
.minimizeAlign
)
3017 // If padded size of 64KB block is larger than padded size of 256B block or 4KB
3018 // block, filter out 64KB block from candidate list
3019 if (blockSet
.macro64KB
&&
3020 ((blockSet
.micro
&& (padSize
[AddrBlockMicro
] < padSize
[AddrBlock64KB
])) ||
3021 (blockSet
.macro4KB
&& (padSize
[AddrBlock4KB
] < padSize
[AddrBlock64KB
]))))
3023 blockSet
.macro64KB
= FALSE
;
3026 // If padded size of 4KB block is larger than padded size of 256B block,
3027 // filter out 4KB block from candidate list
3028 if (blockSet
.macro4KB
&&
3030 (padSize
[AddrBlockMicro
] < padSize
[AddrBlock4KB
]))
3032 blockSet
.macro4KB
= FALSE
;
3035 // Filter out 64KB/4KB block if a smaller block type has 2/3 or less memory footprint
3036 else if (pIn
->flags
.opt4space
)
3040 padSize
[AddrBlockMicro
] :
3041 (blockSet
.macro4KB
? padSize
[AddrBlock4KB
] : padSize
[AddrBlock64KB
]);
3043 threshold
+= threshold
>> 1;
3045 if (blockSet
.macro64KB
&& (padSize
[AddrBlock64KB
] > threshold
))
3047 blockSet
.macro64KB
= FALSE
;
3050 if (blockSet
.macro4KB
&& (padSize
[AddrBlock4KB
] > threshold
))
3052 blockSet
.macro4KB
= FALSE
;
3056 if (blockSet
.value
== 0)
3058 // Bad things happen, client will not get any useful information from AddrLib.
3059 // Maybe we should fill in some output earlier instead of outputing nothing?
3060 ADDR_ASSERT_ALWAYS();
3061 returnCode
= ADDR_INVALIDPARAMS
;
3065 pOut
->validBlockSet
= blockSet
;
3066 pOut
->canXor
= (pIn
->flags
.prt
== FALSE
) &&
3067 (blockSet
.macro4KB
|| blockSet
.macro64KB
|| blockSet
.var
);
3069 if (blockSet
.macro64KB
|| blockSet
.macro4KB
)
3071 if (swType
== ADDR_SW_Z
)
3073 pOut
->swizzleMode
= blockSet
.macro64KB
? ADDR_SW_64KB_Z
: ADDR_SW_4KB_Z
;
3075 else if (swType
== ADDR_SW_S
)
3077 pOut
->swizzleMode
= blockSet
.macro64KB
? ADDR_SW_64KB_S
: ADDR_SW_4KB_S
;
3079 else if (swType
== ADDR_SW_D
)
3081 pOut
->swizzleMode
= blockSet
.macro64KB
? ADDR_SW_64KB_D
: ADDR_SW_4KB_D
;
3085 ADDR_ASSERT(swType
== ADDR_SW_R
);
3086 pOut
->swizzleMode
= blockSet
.macro64KB
? ADDR_SW_64KB_R
: ADDR_SW_4KB_R
;
3089 if (pIn
->noXor
== FALSE
)
3091 if (tryPrtXor
&& blockSet
.macro64KB
)
3093 // Client wants PRTXOR, give back _T swizzle mode if 64KB is available
3094 static const UINT_32 PrtGap
= ADDR_SW_64KB_Z_T
- ADDR_SW_64KB_Z
;
3096 static_cast<AddrSwizzleMode
>(pOut
->swizzleMode
+ PrtGap
);
3098 else if (pOut
->canXor
)
3100 // Client wants XOR and this is allowed, return XOR version swizzle mode
3101 static const UINT_32 XorGap
= ADDR_SW_4KB_Z_X
- ADDR_SW_4KB_Z
;
3103 static_cast<AddrSwizzleMode
>(pOut
->swizzleMode
+ XorGap
);
3107 else if (blockSet
.var
)
3109 // Designer consider this swizzle is usless for most cases
3110 ADDR_UNHANDLED_CASE();
3112 else if (blockSet
.micro
)
3114 if (swType
== ADDR_SW_S
)
3116 pOut
->swizzleMode
= ADDR_SW_256B_S
;
3118 else if (swType
== ADDR_SW_D
)
3120 pOut
->swizzleMode
= ADDR_SW_256B_D
;
3124 ADDR_ASSERT(swType
== ADDR_SW_R
);
3125 pOut
->swizzleMode
= ADDR_SW_256B_R
;
3130 ADDR_ASSERT(blockSet
.linear
);
3131 // Fall into this branch doesn't mean linear is suitable, only no other choices!
3132 pOut
->swizzleMode
= ADDR_SW_LINEAR
;
3136 // Post sanity check, at least AddrLib should accept the output generated by its own
3137 if (pOut
->swizzleMode
!= ADDR_SW_LINEAR
)
3139 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {0};
3140 localIn
.flags
= pIn
->flags
;
3141 localIn
.swizzleMode
= pOut
->swizzleMode
;
3142 localIn
.resourceType
= pOut
->resourceType
;
3143 localIn
.format
= pIn
->format
;
3145 localIn
.width
= width
;
3146 localIn
.height
= height
;
3147 localIn
.numSlices
= slice
;
3148 localIn
.numMipLevels
= numMipLevels
;
3149 localIn
.numSamples
= numSamples
;
3150 localIn
.numFrags
= numFrags
;
3152 ADDR_E_RETURNCODE coherentCheck
= ComputeSurfaceInfoSanityCheck(&localIn
);
3153 ADDR_ASSERT(coherentCheck
== ADDR_OK
);
3155 // TODO : check all valid block type available in validBlockSet?
3166 ****************************************************************************************************
3167 * Lib::ComputeBlock256Equation
3170 * Compute equation for block 256B
3173 * If equation computed successfully
3175 ****************************************************************************************************
3177 ADDR_E_RETURNCODE
Lib::ComputeBlock256Equation(
3178 AddrResourceType rsrcType
,
3179 AddrSwizzleMode swMode
,
3180 UINT_32 elementBytesLog2
,
3181 ADDR_EQUATION
* pEquation
) const
3183 ADDR_E_RETURNCODE ret
;
3185 if (IsBlock256b(swMode
))
3187 ret
= HwlComputeBlock256Equation(rsrcType
, swMode
, elementBytesLog2
, pEquation
);
3191 ADDR_ASSERT_ALWAYS();
3192 ret
= ADDR_INVALIDPARAMS
;
3199 ****************************************************************************************************
3200 * Lib::ComputeThinEquation
3203 * Compute equation for 2D/3D resource which use THIN mode
3206 * If equation computed successfully
3208 ****************************************************************************************************
3210 ADDR_E_RETURNCODE
Lib::ComputeThinEquation(
3211 AddrResourceType rsrcType
,
3212 AddrSwizzleMode swMode
,
3213 UINT_32 elementBytesLog2
,
3214 ADDR_EQUATION
* pEquation
) const
3216 ADDR_E_RETURNCODE ret
;
3218 if (IsThin(rsrcType
, swMode
))
3220 ret
= HwlComputeThinEquation(rsrcType
, swMode
, elementBytesLog2
, pEquation
);
3224 ADDR_ASSERT_ALWAYS();
3225 ret
= ADDR_INVALIDPARAMS
;
3232 ****************************************************************************************************
3233 * Lib::ComputeThickEquation
3236 * Compute equation for 3D resource which use THICK mode
3239 * If equation computed successfully
3241 ****************************************************************************************************
3243 ADDR_E_RETURNCODE
Lib::ComputeThickEquation(
3244 AddrResourceType rsrcType
,
3245 AddrSwizzleMode swMode
,
3246 UINT_32 elementBytesLog2
,
3247 ADDR_EQUATION
* pEquation
) const
3249 ADDR_E_RETURNCODE ret
;
3251 if (IsThick(rsrcType
, swMode
))
3253 ret
= HwlComputeThickEquation(rsrcType
, swMode
, elementBytesLog2
, pEquation
);
3257 ADDR_ASSERT_ALWAYS();
3258 ret
= ADDR_INVALIDPARAMS
;