2
************************************************************************************************************************
4
* Copyright (C) 2007-2022 Advanced Micro Devices, Inc. All rights reserved.
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the "Software"),
8
* to deal in the Software without restriction, including without limitation
9
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
* and/or sell copies of the Software, and to permit persons to whom the
11
* Software is furnished to do so, subject to the following conditions:
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
* OTHER DEALINGS IN THE SOFTWARE
24
***********************************************************************************************************************/
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 Dim2d Lib::Block256_2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}};
49
const Dim3d Lib::Block1K_3d[] = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}};
51
////////////////////////////////////////////////////////////////////////////////////////////////////
52
// Constructor/Destructor
53
////////////////////////////////////////////////////////////////////////////////////////////////////
56
************************************************************************************************************************
60
* Constructor for the Addr::V2::Lib class
62
************************************************************************************************************************
75
m_pipeInterleaveLog2(0),
76
m_blockVarSizeLog2(0),
82
************************************************************************************************************************
86
* Constructor for the AddrLib2 class with hClient as parameter
88
************************************************************************************************************************
90
Lib::Lib(const Client* pClient)
100
m_maxCompFragLog2(0),
101
m_pipeInterleaveLog2(0),
102
m_blockVarSizeLog2(0),
108
************************************************************************************************************************
112
* Destructor for the AddrLib2 class
114
************************************************************************************************************************
121
************************************************************************************************************************
125
* Get Addr::V2::Lib pointer
128
* An Addr::V2::Lib class pointer
129
************************************************************************************************************************
132
ADDR_HANDLE hLib) ///< [in] handle of ADDR_HANDLE
134
Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib);
135
if ((pAddrLib != NULL) &&
136
(pAddrLib->GetChipFamily() <= ADDR_CHIP_FAMILY_VI))
138
// only valid and GFX9+ ASIC can use AddrLib2 function.
139
ADDR_ASSERT_ALWAYS();
142
return static_cast<Lib*>(hLib);
146
////////////////////////////////////////////////////////////////////////////////////////////////////
148
////////////////////////////////////////////////////////////////////////////////////////////////////
152
************************************************************************************************************************
153
* Lib::ComputeSurfaceInfo
156
* Interface function stub of AddrComputeSurfaceInfo.
160
************************************************************************************************************************
162
ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
163
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
164
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
167
ADDR_E_RETURNCODE returnCode = ADDR_OK;
169
if (GetFillSizeFieldsFlags() == TRUE)
171
if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)) ||
172
(pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT)))
174
returnCode = ADDR_PARAMSIZEMISMATCH;
178
// Adjust coming parameters.
179
ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
180
localIn.width = Max(pIn->width, 1u);
181
localIn.height = Max(pIn->height, 1u);
182
localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
183
localIn.numSlices = Max(pIn->numSlices, 1u);
184
localIn.numSamples = Max(pIn->numSamples, 1u);
185
localIn.numFrags = (localIn.numFrags == 0) ? localIn.numSamples : pIn->numFrags;
189
ElemMode elemMode = ADDR_UNCOMPRESSED;
191
if (returnCode == ADDR_OK)
193
// Set format to INVALID will skip this conversion
194
if (localIn.format != ADDR_FMT_INVALID)
196
// Get compression/expansion factors and element mode which indicates compression/expansion
197
localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,
202
// Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
203
// pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
204
// aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
205
// restrictions are different.
206
// Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
207
// but we use this flag to skip RestoreSurfaceInfo below
209
if ((elemMode == ADDR_EXPANDED) && (expandX > 1))
211
ADDR_ASSERT(IsLinear(localIn.swizzleMode));
214
UINT_32 basePitch = 0;
215
GetElemLib()->AdjustSurfaceInfo(elemMode,
223
// Overwrite these parameters if we have a valid format
226
if (localIn.bpp != 0)
228
localIn.width = Max(localIn.width, 1u);
229
localIn.height = Max(localIn.height, 1u);
231
else // Rule out some invalid parameters
233
ADDR_ASSERT_ALWAYS();
235
returnCode = ADDR_INVALIDPARAMS;
239
if (returnCode == ADDR_OK)
241
returnCode = ComputeSurfaceInfoSanityCheck(&localIn);
244
if (returnCode == ADDR_OK)
246
VerifyMipLevelInfo(pIn);
248
if (IsLinear(pIn->swizzleMode))
251
returnCode = ComputeSurfaceInfoLinear(&localIn, pOut);
256
returnCode = ComputeSurfaceInfoTiled(&localIn, pOut);
259
if (returnCode == ADDR_OK)
261
pOut->bpp = localIn.bpp;
262
pOut->pixelPitch = pOut->pitch;
263
pOut->pixelHeight = pOut->height;
264
pOut->pixelMipChainPitch = pOut->mipChainPitch;
265
pOut->pixelMipChainHeight = pOut->mipChainHeight;
266
pOut->pixelBits = localIn.bpp;
268
if (localIn.format != ADDR_FMT_INVALID)
270
UINT_32 pixelBits = pOut->pixelBits;
272
GetElemLib()->RestoreSurfaceInfo(elemMode,
279
GetElemLib()->RestoreSurfaceInfo(elemMode,
283
&pOut->pixelMipChainPitch,
284
&pOut->pixelMipChainHeight);
286
if ((localIn.numMipLevels > 1) && (pOut->pMipInfo != NULL))
288
for (UINT_32 i = 0; i < localIn.numMipLevels; i++)
290
pOut->pMipInfo[i].pixelPitch = pOut->pMipInfo[i].pitch;
291
pOut->pMipInfo[i].pixelHeight = pOut->pMipInfo[i].height;
293
GetElemLib()->RestoreSurfaceInfo(elemMode,
297
&pOut->pMipInfo[i].pixelPitch,
298
&pOut->pMipInfo[i].pixelHeight);
303
if (localIn.flags.needEquation && (Log2(localIn.numFrags) == 0))
305
pOut->equationIndex = GetEquationIndex(&localIn, pOut);
308
if (localIn.flags.qbStereo)
310
if (pOut->pStereoInfo != NULL)
312
ComputeQbStereoInfo(pOut);
314
ValidateStereoInfo(pIn, pOut);
321
ADDR_ASSERT(pOut->surfSize != 0);
323
ValidBaseAlignments(pOut->baseAlign);
329
************************************************************************************************************************
330
* Lib::ComputeSurfaceInfo
333
* Interface function stub of AddrComputeSurfaceInfo.
337
************************************************************************************************************************
339
ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord(
340
const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
341
ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
344
ADDR_E_RETURNCODE returnCode = ADDR_OK;
346
if (GetFillSizeFieldsFlags() == TRUE)
348
if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
349
(pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
351
returnCode = ADDR_PARAMSIZEMISMATCH;
355
ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn = *pIn;
356
localIn.unalignedWidth = Max(pIn->unalignedWidth, 1u);
357
localIn.unalignedHeight = Max(pIn->unalignedHeight, 1u);
358
localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
359
localIn.numSlices = Max(pIn->numSlices, 1u);
360
localIn.numSamples = Max(pIn->numSamples, 1u);
361
localIn.numFrags = Max(pIn->numFrags, 1u);
363
if ((localIn.bpp < 8) ||
364
(localIn.bpp > 128) ||
365
((localIn.bpp % 8) != 0) ||
366
(localIn.sample >= localIn.numSamples) ||
367
(localIn.slice >= localIn.numSlices) ||
368
(localIn.mipId >= localIn.numMipLevels) ||
369
(IsTex3d(localIn.resourceType) &&
370
(Valid3DMipSliceIdConstraint(localIn.numSlices, localIn.mipId, localIn.slice) == FALSE)))
372
returnCode = ADDR_INVALIDPARAMS;
375
if (returnCode == ADDR_OK)
377
if (IsLinear(localIn.swizzleMode))
379
returnCode = ComputeSurfaceAddrFromCoordLinear(&localIn, pOut);
383
returnCode = ComputeSurfaceAddrFromCoordTiled(&localIn, pOut);
386
if (returnCode == ADDR_OK)
388
pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
396
************************************************************************************************************************
397
* Lib::ComputeSurfaceCoordFromAddr
400
* Interface function stub of ComputeSurfaceCoordFromAddr.
404
************************************************************************************************************************
406
ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr(
407
const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
408
ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
411
ADDR_E_RETURNCODE returnCode = ADDR_OK;
413
if (GetFillSizeFieldsFlags() == TRUE)
415
if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||
416
(pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))
418
returnCode = ADDR_PARAMSIZEMISMATCH;
422
if ((pIn->bpp < 8) ||
424
((pIn->bpp % 8) != 0) ||
425
(pIn->bitPosition >= 8))
427
returnCode = ADDR_INVALIDPARAMS;
430
if (returnCode == ADDR_OK)
432
if (IsLinear(pIn->swizzleMode))
434
returnCode = ComputeSurfaceCoordFromAddrLinear(pIn, pOut);
438
returnCode = ComputeSurfaceCoordFromAddrTiled(pIn, pOut);
446
////////////////////////////////////////////////////////////////////////////////////////////////////
448
////////////////////////////////////////////////////////////////////////////////////////////////////
451
************************************************************************************************************************
452
* Lib::ComputeHtileInfo
455
* Interface function stub of AddrComputeHtilenfo
459
************************************************************************************************************************
461
ADDR_E_RETURNCODE Lib::ComputeHtileInfo(
462
const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure
463
ADDR2_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure
466
ADDR_E_RETURNCODE returnCode;
468
if ((GetFillSizeFieldsFlags() == TRUE) &&
469
((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)) ||
470
(pOut->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT))))
472
returnCode = ADDR_INVALIDPARAMS;
476
returnCode = HwlComputeHtileInfo(pIn, pOut);
478
ValidMetaBaseAlignments(pOut->baseAlign);
485
************************************************************************************************************************
486
* Lib::ComputeHtileAddrFromCoord
489
* Interface function stub of AddrComputeHtileAddrFromCoord
493
************************************************************************************************************************
495
ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord(
496
const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
497
ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
499
ADDR_E_RETURNCODE returnCode;
501
if ((GetFillSizeFieldsFlags() == TRUE) &&
502
((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||
503
(pOut->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT))))
505
returnCode = ADDR_INVALIDPARAMS;
509
returnCode = HwlComputeHtileAddrFromCoord(pIn, pOut);
516
************************************************************************************************************************
517
* Lib::ComputeHtileCoordFromAddr
520
* Interface function stub of AddrComputeHtileCoordFromAddr
524
************************************************************************************************************************
526
ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr(
527
const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
528
ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut) ///< [out] output structure
530
ADDR_E_RETURNCODE returnCode;
532
if ((GetFillSizeFieldsFlags() == TRUE) &&
533
((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||
534
(pOut->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT))))
536
returnCode = ADDR_INVALIDPARAMS;
540
returnCode = HwlComputeHtileCoordFromAddr(pIn, pOut);
547
************************************************************************************************************************
548
* Lib::ComputeCmaskInfo
551
* Interface function stub of AddrComputeCmaskInfo
555
************************************************************************************************************************
557
ADDR_E_RETURNCODE Lib::ComputeCmaskInfo(
558
const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure
559
ADDR2_COMPUTE_CMASK_INFO_OUTPUT* pOut ///< [out] output structure
562
ADDR_E_RETURNCODE returnCode;
564
if ((GetFillSizeFieldsFlags() == TRUE) &&
565
((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT)) ||
566
(pOut->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT))))
568
returnCode = ADDR_INVALIDPARAMS;
570
else if (pIn->cMaskFlags.linear)
572
returnCode = ADDR_INVALIDPARAMS;
576
returnCode = HwlComputeCmaskInfo(pIn, pOut);
578
ValidMetaBaseAlignments(pOut->baseAlign);
585
************************************************************************************************************************
586
* Lib::ComputeCmaskAddrFromCoord
589
* Interface function stub of AddrComputeCmaskAddrFromCoord
593
************************************************************************************************************************
595
ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord(
596
const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
597
ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
599
ADDR_E_RETURNCODE returnCode;
601
if ((GetFillSizeFieldsFlags() == TRUE) &&
602
((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||
603
(pOut->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT))))
605
returnCode = ADDR_INVALIDPARAMS;
609
returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);
616
************************************************************************************************************************
617
* Lib::ComputeCmaskCoordFromAddr
620
* Interface function stub of AddrComputeCmaskCoordFromAddr
624
************************************************************************************************************************
626
ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr(
627
const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
628
ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
631
ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
633
ADDR_NOT_IMPLEMENTED();
639
************************************************************************************************************************
640
* Lib::ComputeFmaskInfo
643
* Interface function stub of ComputeFmaskInfo.
647
************************************************************************************************************************
649
ADDR_E_RETURNCODE Lib::ComputeFmaskInfo(
650
const ADDR2_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
651
ADDR2_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure
654
ADDR_E_RETURNCODE returnCode;
656
BOOL_32 valid = (IsZOrderSwizzle(pIn->swizzleMode) == TRUE) &&
657
((pIn->numSamples > 0) || (pIn->numFrags > 0));
659
if (GetFillSizeFieldsFlags())
661
if ((pIn->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT)) ||
662
(pOut->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT)))
670
returnCode = ADDR_INVALIDPARAMS;
674
ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
675
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
677
localIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT);
678
localOut.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT);
680
localIn.swizzleMode = pIn->swizzleMode;
681
localIn.numSlices = Max(pIn->numSlices, 1u);
682
localIn.width = Max(pIn->unalignedWidth, 1u);
683
localIn.height = Max(pIn->unalignedHeight, 1u);
684
localIn.bpp = GetFmaskBpp(pIn->numSamples, pIn->numFrags);
685
localIn.flags.fmask = 1;
686
localIn.numFrags = 1;
687
localIn.numSamples = 1;
688
localIn.resourceType = ADDR_RSRC_TEX_2D;
690
if (localIn.bpp == 8)
692
localIn.format = ADDR_FMT_8;
694
else if (localIn.bpp == 16)
696
localIn.format = ADDR_FMT_16;
698
else if (localIn.bpp == 32)
700
localIn.format = ADDR_FMT_32;
704
localIn.format = ADDR_FMT_32_32;
707
returnCode = ComputeSurfaceInfo(&localIn, &localOut);
709
if (returnCode == ADDR_OK)
711
pOut->pitch = localOut.pitch;
712
pOut->height = localOut.height;
713
pOut->baseAlign = localOut.baseAlign;
714
pOut->numSlices = localOut.numSlices;
715
pOut->fmaskBytes = static_cast<UINT_32>(localOut.surfSize);
716
pOut->sliceSize = static_cast<UINT_32>(localOut.sliceSize);
717
pOut->bpp = localIn.bpp;
718
pOut->numSamples = 1;
722
ValidBaseAlignments(pOut->baseAlign);
728
************************************************************************************************************************
729
* Lib::ComputeFmaskAddrFromCoord
732
* Interface function stub of ComputeFmaskAddrFromCoord.
736
************************************************************************************************************************
738
ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord(
739
const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
740
ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
743
ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
745
ADDR_NOT_IMPLEMENTED();
751
************************************************************************************************************************
752
* Lib::ComputeFmaskCoordFromAddr
755
* Interface function stub of ComputeFmaskAddrFromCoord.
759
************************************************************************************************************************
761
ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr(
762
const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
763
ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
766
ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
768
ADDR_NOT_IMPLEMENTED();
774
************************************************************************************************************************
775
* Lib::ComputeDccInfo
778
* Interface function to compute DCC key info
781
* return code of HwlComputeDccInfo
782
************************************************************************************************************************
784
ADDR_E_RETURNCODE Lib::ComputeDccInfo(
785
const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure
786
ADDR2_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure
789
ADDR_E_RETURNCODE returnCode;
791
if ((GetFillSizeFieldsFlags() == TRUE) &&
792
((pIn->size != sizeof(ADDR2_COMPUTE_DCCINFO_INPUT)) ||
793
(pOut->size != sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT))))
795
returnCode = ADDR_INVALIDPARAMS;
799
returnCode = HwlComputeDccInfo(pIn, pOut);
801
ValidMetaBaseAlignments(pOut->dccRamBaseAlign);
808
************************************************************************************************************************
809
* Lib::ComputeDccAddrFromCoord
812
* Interface function stub of ComputeDccAddrFromCoord
816
************************************************************************************************************************
818
ADDR_E_RETURNCODE Lib::ComputeDccAddrFromCoord(
819
const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
820
ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
822
ADDR_E_RETURNCODE returnCode;
824
if ((GetFillSizeFieldsFlags() == TRUE) &&
825
((pIn->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT)) ||
826
(pOut->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT))))
828
returnCode = ADDR_INVALIDPARAMS;
832
returnCode = HwlSupportComputeDccAddrFromCoord(pIn);
834
if (returnCode == ADDR_OK)
836
HwlComputeDccAddrFromCoord(pIn, pOut);
844
************************************************************************************************************************
845
* Lib::ComputePipeBankXor
848
* Interface function stub of Addr2ComputePipeBankXor.
852
************************************************************************************************************************
854
ADDR_E_RETURNCODE Lib::ComputePipeBankXor(
855
const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,
856
ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut)
858
ADDR_E_RETURNCODE returnCode;
860
if ((GetFillSizeFieldsFlags() == TRUE) &&
861
((pIn->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT)) ||
862
(pOut->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT))))
864
returnCode = ADDR_INVALIDPARAMS;
868
returnCode = HwlComputePipeBankXor(pIn, pOut);
875
************************************************************************************************************************
876
* Lib::ComputeSlicePipeBankXor
879
* Interface function stub of Addr2ComputeSlicePipeBankXor.
883
************************************************************************************************************************
885
ADDR_E_RETURNCODE Lib::ComputeSlicePipeBankXor(
886
const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,
887
ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut)
889
ADDR_E_RETURNCODE returnCode;
891
if ((GetFillSizeFieldsFlags() == TRUE) &&
892
((pIn->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT)) ||
893
(pOut->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT))))
895
returnCode = ADDR_INVALIDPARAMS;
897
else if ((IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE) ||
898
(IsNonPrtXor(pIn->swizzleMode) == FALSE) ||
899
(pIn->numSamples > 1))
901
returnCode = ADDR_NOTSUPPORTED;
903
else if ((pIn->bpe != 0) &&
910
returnCode = ADDR_INVALIDPARAMS;
914
returnCode = HwlComputeSlicePipeBankXor(pIn, pOut);
921
************************************************************************************************************************
922
* Lib::ComputeSubResourceOffsetForSwizzlePattern
925
* Interface function stub of Addr2ComputeSubResourceOffsetForSwizzlePattern.
929
************************************************************************************************************************
931
ADDR_E_RETURNCODE Lib::ComputeSubResourceOffsetForSwizzlePattern(
932
const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,
933
ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut)
935
ADDR_E_RETURNCODE returnCode;
937
if ((GetFillSizeFieldsFlags() == TRUE) &&
938
((pIn->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT)) ||
939
(pOut->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT))))
941
returnCode = ADDR_INVALIDPARAMS;
945
returnCode = HwlComputeSubResourceOffsetForSwizzlePattern(pIn, pOut);
952
************************************************************************************************************************
953
* Lib::ComputeNonBlockCompressedView
956
* Interface function stub of Addr2ComputeNonBlockCompressedView.
960
************************************************************************************************************************
962
ADDR_E_RETURNCODE Lib::ComputeNonBlockCompressedView(
963
const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,
964
ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT* pOut)
966
ADDR_E_RETURNCODE returnCode;
968
if ((GetFillSizeFieldsFlags() == TRUE) &&
969
((pIn->size != sizeof(ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT)) ||
970
(pOut->size != sizeof(ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT))))
972
returnCode = ADDR_INVALIDPARAMS;
976
returnCode = HwlComputeNonBlockCompressedView(pIn, pOut);
983
************************************************************************************************************************
984
* Lib::ExtractPipeBankXor
987
* Internal function to extract bank and pipe xor bits from combined xor bits.
991
************************************************************************************************************************
993
ADDR_E_RETURNCODE Lib::ExtractPipeBankXor(
1000
ADDR_E_RETURNCODE returnCode;
1002
if (pipeBankXor < (1u << (pipeBits + bankBits)))
1004
*pPipeX = pipeBankXor % (1 << pipeBits);
1005
*pBankX = pipeBankXor >> pipeBits;
1006
returnCode = ADDR_OK;
1010
ADDR_ASSERT_ALWAYS();
1011
returnCode = ADDR_INVALIDPARAMS;
1018
************************************************************************************************************************
1019
* Lib::ComputeSurfaceInfoSanityCheck
1022
* Internal function to do basic sanity check before compute surface info
1026
************************************************************************************************************************
1028
ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoSanityCheck(
1029
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in] input structure
1032
ADDR_E_RETURNCODE returnCode;
1034
if ((GetFillSizeFieldsFlags() == TRUE) &&
1035
(pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)))
1037
returnCode = ADDR_INVALIDPARAMS;
1041
returnCode = HwlComputeSurfaceInfoSanityCheck(pIn);
1048
************************************************************************************************************************
1049
* Lib::ApplyCustomizedPitchHeight
1052
* Helper function to override hw required row pitch/slice pitch by customrized one
1056
************************************************************************************************************************
1058
ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight(
1059
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
1060
UINT_32 elementBytes, ///< [in] element bytes per element
1061
UINT_32 pitchAlignInElement, ///< [in] pitch alignment in element
1062
UINT_32* pPitch, ///< [in/out] pitch
1063
UINT_32* pHeight ///< [in/out] height
1066
ADDR_E_RETURNCODE returnCode = ADDR_OK;
1068
if (pIn->numMipLevels <= 1)
1070
if (pIn->pitchInElement > 0)
1072
if ((pIn->pitchInElement % pitchAlignInElement) != 0)
1074
returnCode = ADDR_INVALIDPARAMS;
1076
else if (pIn->pitchInElement < (*pPitch))
1078
returnCode = ADDR_INVALIDPARAMS;
1082
*pPitch = pIn->pitchInElement;
1086
if (returnCode == ADDR_OK)
1088
if (pIn->sliceAlign > 0)
1090
UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / (*pPitch);
1092
if (customizedHeight * elementBytes * (*pPitch) != pIn->sliceAlign)
1094
returnCode = ADDR_INVALIDPARAMS;
1096
else if ((pIn->numSlices > 1) && ((*pHeight) != customizedHeight))
1098
returnCode = ADDR_INVALIDPARAMS;
1102
*pHeight = customizedHeight;
1112
************************************************************************************************************************
1113
* Lib::ComputeSurfaceInfoLinear
1116
* Internal function to calculate alignment for linear swizzle surface
1120
************************************************************************************************************************
1122
ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear(
1123
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
1124
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
1127
return HwlComputeSurfaceInfoLinear(pIn, pOut);
1131
************************************************************************************************************************
1132
* Lib::ComputeSurfaceInfoTiled
1135
* Internal function to calculate alignment for tiled swizzle surface
1139
************************************************************************************************************************
1141
ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoTiled(
1142
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
1143
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
1146
return HwlComputeSurfaceInfoTiled(pIn, pOut);
1150
************************************************************************************************************************
1151
* Lib::ComputeSurfaceAddrFromCoordLinear
1154
* Internal function to calculate address from coord for linear swizzle surface
1158
************************************************************************************************************************
1160
ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear(
1161
const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1162
ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
1165
ADDR_E_RETURNCODE returnCode = ADDR_OK;
1166
BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1) && (pIn->pipeBankXor == 0);
1170
if (IsTex1d(pIn->resourceType))
1172
valid = (pIn->y == 0);
1178
ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
1179
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
1180
ADDR2_MIP_INFO mipInfo[MaxMipLevels];
1182
localIn.bpp = pIn->bpp;
1183
localIn.flags = pIn->flags;
1184
localIn.width = Max(pIn->unalignedWidth, 1u);
1185
localIn.height = Max(pIn->unalignedHeight, 1u);
1186
localIn.numSlices = Max(pIn->numSlices, 1u);
1187
localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
1188
localIn.resourceType = pIn->resourceType;
1190
if (localIn.numMipLevels <= 1)
1192
localIn.pitchInElement = pIn->pitchInElement;
1195
localOut.pMipInfo = mipInfo;
1197
returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);
1199
if (returnCode == ADDR_OK)
1201
pOut->addr = (localOut.sliceSize * pIn->slice) +
1202
mipInfo[pIn->mipId].offset +
1203
(pIn->y * mipInfo[pIn->mipId].pitch + pIn->x) * (pIn->bpp >> 3);
1204
pOut->bitPosition = 0;
1214
returnCode = ADDR_INVALIDPARAMS;
1221
************************************************************************************************************************
1222
* Lib::ComputeSurfaceAddrFromCoordTiled
1225
* Internal function to calculate address from coord for tiled swizzle surface
1229
************************************************************************************************************************
1231
ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordTiled(
1232
const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1233
ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
1236
return HwlComputeSurfaceAddrFromCoordTiled(pIn, pOut);
1240
************************************************************************************************************************
1241
* Lib::ComputeSurfaceCoordFromAddrLinear
1244
* Internal function to calculate coord from address for linear swizzle surface
1248
************************************************************************************************************************
1250
ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear(
1251
const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
1252
ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
1255
ADDR_E_RETURNCODE returnCode = ADDR_OK;
1257
BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1);
1261
if (IsTex1d(pIn->resourceType))
1263
valid = (pIn->unalignedHeight == 1);
1269
ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
1270
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
1271
localIn.bpp = pIn->bpp;
1272
localIn.flags = pIn->flags;
1273
localIn.width = Max(pIn->unalignedWidth, 1u);
1274
localIn.height = Max(pIn->unalignedHeight, 1u);
1275
localIn.numSlices = Max(pIn->numSlices, 1u);
1276
localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
1277
localIn.resourceType = pIn->resourceType;
1278
if (localIn.numMipLevels <= 1)
1280
localIn.pitchInElement = pIn->pitchInElement;
1282
returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);
1284
if (returnCode == ADDR_OK)
1286
pOut->slice = static_cast<UINT_32>(pIn->addr / localOut.sliceSize);
1289
UINT_32 offsetInSlice = static_cast<UINT_32>(pIn->addr % localOut.sliceSize);
1290
UINT_32 elementBytes = pIn->bpp >> 3;
1291
UINT_32 mipOffsetInSlice = 0;
1292
UINT_32 mipSize = 0;
1294
for (; mipId < pIn->numMipLevels ; mipId++)
1296
if (IsTex1d(pIn->resourceType))
1298
mipSize = localOut.pitch * elementBytes;
1302
UINT_32 currentMipHeight = (PowTwoAlign(localIn.height, (1 << mipId))) >> mipId;
1303
mipSize = currentMipHeight * localOut.pitch * elementBytes;
1311
else if ((mipSize + mipOffsetInSlice) > offsetInSlice)
1317
mipOffsetInSlice += mipSize;
1318
if ((mipId == (pIn->numMipLevels - 1)) ||
1319
(mipOffsetInSlice >= localOut.sliceSize))
1328
pOut->mipId = mipId;
1330
UINT_32 elemOffsetInMip = (offsetInSlice - mipOffsetInSlice) / elementBytes;
1331
if (IsTex1d(pIn->resourceType))
1333
if (elemOffsetInMip < localOut.pitch)
1335
pOut->x = elemOffsetInMip;
1345
pOut->y = elemOffsetInMip / localOut.pitch;
1346
pOut->x = elemOffsetInMip % localOut.pitch;
1349
if ((pOut->slice >= pIn->numSlices) ||
1350
(pOut->mipId >= pIn->numMipLevels) ||
1351
(pOut->x >= Max((pIn->unalignedWidth >> pOut->mipId), 1u)) ||
1352
(pOut->y >= Max((pIn->unalignedHeight >> pOut->mipId), 1u)) ||
1353
(IsTex3d(pIn->resourceType) &&
1354
(FALSE == Valid3DMipSliceIdConstraint(pIn->numSlices,
1370
returnCode = ADDR_INVALIDPARAMS;
1377
************************************************************************************************************************
1378
* Lib::ComputeSurfaceCoordFromAddrTiled
1381
* Internal function to calculate coord from address for tiled swizzle surface
1385
************************************************************************************************************************
1387
ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled(
1388
const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
1389
ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
1392
ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
1394
ADDR_NOT_IMPLEMENTED();
1400
************************************************************************************************************************
1401
* Lib::ComputeBlockDimensionForSurf
1404
* Internal function to get block width/height/depth in element from surface input params.
1408
************************************************************************************************************************
1410
ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf(
1416
AddrResourceType resourceType,
1417
AddrSwizzleMode swizzleMode) const
1419
ADDR_E_RETURNCODE returnCode = ADDR_OK;
1421
if (IsThick(resourceType, swizzleMode))
1423
ComputeThickBlockDimension(pWidth, pHeight, pDepth, bpp, resourceType, swizzleMode);
1425
else if (IsThin(resourceType, swizzleMode))
1427
ComputeThinBlockDimension(pWidth, pHeight, pDepth, bpp, numSamples, resourceType, swizzleMode);
1431
ADDR_ASSERT_ALWAYS();
1432
returnCode = ADDR_INVALIDPARAMS;
1439
************************************************************************************************************************
1440
* Lib::ComputeThinBlockDimension
1443
* Internal function to get thin block width/height/depth in element from surface input params.
1447
************************************************************************************************************************
1449
VOID Lib::ComputeThinBlockDimension(
1455
AddrResourceType resourceType,
1456
AddrSwizzleMode swizzleMode) const
1458
ADDR_ASSERT(IsThin(resourceType, swizzleMode));
1460
// GFX9/GFX10 use different dimension amplifying logic: say for 128KB block + 1xAA + 1BPE, the dimension of thin
1461
// swizzle mode will be [256W * 512H] on GFX9 ASICs and [512W * 256H] on GFX10 ASICs. Since GFX10 is newer HWL so we
1462
// make its implementation into base class (in order to save future change on new HWLs)
1463
const UINT_32 log2BlkSize = GetBlockSizeLog2(swizzleMode);
1464
const UINT_32 log2EleBytes = Log2(bpp >> 3);
1465
const UINT_32 log2Samples = Log2(Max(numSamples, 1u));
1466
const UINT_32 log2NumEle = log2BlkSize - log2EleBytes - log2Samples;
1468
// For "1xAA/4xAA cases" or "2xAA/8xAA + odd log2BlkSize cases", width == height or width == 2 * height;
1469
// For other cases, height == width or height == 2 * width
1470
const BOOL_32 widthPrecedent = ((log2Samples & 1) == 0) || ((log2BlkSize & 1) != 0);
1471
const UINT_32 log2Width = (log2NumEle + (widthPrecedent ? 1 : 0)) / 2;
1473
*pWidth = 1u << log2Width;
1474
*pHeight = 1u << (log2NumEle - log2Width);
1479
************************************************************************************************************************
1480
* Lib::ComputeBlockDimension
1483
* Internal function to get block width/height/depth in element without considering MSAA case
1487
************************************************************************************************************************
1489
ADDR_E_RETURNCODE Lib::ComputeBlockDimension(
1494
AddrResourceType resourceType,
1495
AddrSwizzleMode swizzleMode) const
1497
ADDR_E_RETURNCODE returnCode = ADDR_OK;
1499
if (IsThick(resourceType, swizzleMode))
1501
ComputeThickBlockDimension(pWidth, pHeight, pDepth, bpp, resourceType, swizzleMode);
1503
else if (IsThin(resourceType, swizzleMode))
1505
ComputeThinBlockDimension(pWidth, pHeight, pDepth, bpp, 0, resourceType, swizzleMode);
1509
ADDR_ASSERT_ALWAYS();
1510
returnCode = ADDR_INVALIDPARAMS;
1517
************************************************************************************************************************
1518
* Lib::ComputeThickBlockDimension
1521
* Internal function to get block width/height/depth in element for thick swizzle mode
1525
************************************************************************************************************************
1527
VOID Lib::ComputeThickBlockDimension(
1532
AddrResourceType resourceType,
1533
AddrSwizzleMode swizzleMode) const
1535
ADDR_ASSERT(IsThick(resourceType, swizzleMode));
1537
const UINT_32 log2BlkSize = GetBlockSizeLog2(swizzleMode);
1538
const UINT_32 eleBytes = bpp >> 3;
1539
const UINT_32 microBlockSizeTableIndex = Log2(eleBytes);
1541
ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block1K_3d) / sizeof(Block1K_3d[0]));
1543
const UINT_32 log2blkSizeIn1KB = log2BlkSize - 10;
1544
const UINT_32 averageAmp = log2blkSizeIn1KB / 3;
1545
const UINT_32 restAmp = log2blkSizeIn1KB % 3;
1547
*pWidth = Block1K_3d[microBlockSizeTableIndex].w << averageAmp;
1548
*pHeight = Block1K_3d[microBlockSizeTableIndex].h << (averageAmp + (restAmp / 2));
1549
*pDepth = Block1K_3d[microBlockSizeTableIndex].d << (averageAmp + ((restAmp != 0) ? 1 : 0));
1553
************************************************************************************************************************
1554
* Lib::GetMipTailDim
1557
* Internal function to get out max dimension of first level in mip tail
1560
* Max Width/Height/Depth value of the first mip fitted in mip tail
1561
************************************************************************************************************************
1563
Dim3d Lib::GetMipTailDim(
1564
AddrResourceType resourceType,
1565
AddrSwizzleMode swizzleMode,
1567
UINT_32 blockHeight,
1568
UINT_32 blockDepth) const
1570
Dim3d out = {blockWidth, blockHeight, blockDepth};
1571
UINT_32 log2BlkSize = GetBlockSizeLog2(swizzleMode);
1573
if (IsThick(resourceType, swizzleMode))
1575
UINT_32 dim = log2BlkSize % 3;
1592
ADDR_ASSERT(IsThin(resourceType, swizzleMode));
1595
// GFX9/GFX10 use different dimension shrinking logic for mipmap tail: say for 128KB block + 2BPE, the maximum
1596
// dimension of mipmap tail level will be [256W * 128H] on GFX9 ASICs and [128W * 256H] on GFX10 ASICs. Since
1597
// GFX10 is newer HWL so we make its implementation into base class, in order to save future change on new HWLs.
1598
// And assert log2BlkSize will always be an even value on GFX9, so we never need the logic wrapped by DEBUG...
1599
if ((log2BlkSize & 1) && (m_chipFamily == ADDR_CHIP_FAMILY_AI))
1601
// Should never go here...
1602
ADDR_ASSERT_ALWAYS();
1617
************************************************************************************************************************
1618
* Lib::ComputeSurface2DMicroBlockOffset
1621
* Internal function to calculate micro block (256B) offset from coord for 2D resource
1624
* micro block (256B) offset for 2D resource
1625
************************************************************************************************************************
1627
UINT_32 Lib::ComputeSurface2DMicroBlockOffset(
1628
const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const
1630
ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));
1632
UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
1633
UINT_32 microBlockOffset = 0;
1634
if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))
1636
UINT_32 xBits = pIn->x << log2ElementBytes;
1637
microBlockOffset = (xBits & 0xf) | ((pIn->y & 0x3) << 4);
1638
if (log2ElementBytes < 3)
1640
microBlockOffset |= (pIn->y & 0x4) << 4;
1641
if (log2ElementBytes == 0)
1643
microBlockOffset |= (pIn->y & 0x8) << 4;
1647
microBlockOffset |= (xBits & 0x10) << 3;
1652
microBlockOffset |= (xBits & 0x30) << 2;
1655
else if (IsDisplaySwizzle(pIn->resourceType, pIn->swizzleMode))
1657
if (log2ElementBytes == 4)
1659
microBlockOffset = (GetBit(pIn->x, 0) << 4) |
1660
(GetBit(pIn->y, 0) << 5) |
1661
(GetBit(pIn->x, 1) << 6) |
1662
(GetBit(pIn->y, 1) << 7);
1666
microBlockOffset = GetBits(pIn->x, 0, 3, log2ElementBytes) |
1667
GetBits(pIn->y, 1, 2, 3 + log2ElementBytes) |
1668
GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |
1669
GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);
1670
microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |
1671
(GetBit(pIn->y, 0) << 4) |
1672
GetBits(microBlockOffset, 4, 3, 5);
1675
else if (IsRotateSwizzle(pIn->swizzleMode))
1677
microBlockOffset = GetBits(pIn->y, 0, 3, log2ElementBytes) |
1678
GetBits(pIn->x, 1, 2, 3 + log2ElementBytes) |
1679
GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |
1680
GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);
1681
microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |
1682
(GetBit(pIn->x, 0) << 4) |
1683
GetBits(microBlockOffset, 4, 3, 5);
1684
if (log2ElementBytes == 3)
1686
microBlockOffset = GetBits(microBlockOffset, 0, 6, 0) |
1687
GetBits(pIn->x, 1, 2, 6);
1691
return microBlockOffset;
1695
************************************************************************************************************************
1696
* Lib::ComputeSurface3DMicroBlockOffset
1699
* Internal function to calculate micro block (1KB) offset from coord for 3D resource
1702
* micro block (1KB) offset for 3D resource
1703
************************************************************************************************************************
1705
UINT_32 Lib::ComputeSurface3DMicroBlockOffset(
1706
const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const
1708
ADDR_ASSERT(IsThick(pIn->resourceType, pIn->swizzleMode));
1710
UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
1711
UINT_32 microBlockOffset = 0;
1712
if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))
1714
if (log2ElementBytes == 0)
1716
microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);
1718
else if (log2ElementBytes == 1)
1720
microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);
1722
else if (log2ElementBytes == 2)
1724
microBlockOffset = ((pIn->y & 4) >> 2) | ((pIn->x & 4) >> 1);
1726
else if (log2ElementBytes == 3)
1728
microBlockOffset = (pIn->x & 6) >> 1;
1732
microBlockOffset = pIn->x & 3;
1735
microBlockOffset <<= 8;
1737
UINT_32 xBits = pIn->x << log2ElementBytes;
1738
microBlockOffset |= (xBits & 0xf) | ((pIn->y & 0x3) << 4) | ((pIn->slice & 0x3) << 6);
1740
else if (IsZOrderSwizzle(pIn->swizzleMode))
1744
if (log2ElementBytes == 0)
1747
(pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);
1748
microBlockOffset = microBlockOffset | ((pIn->slice & 3) << 4) | ((pIn->x & 4) << 4);
1752
zh = pIn->slice >> 2;
1754
else if (log2ElementBytes == 1)
1757
(pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);
1758
microBlockOffset = (microBlockOffset << 1) | ((pIn->slice & 3) << 5);
1762
zh = pIn->slice >> 2;
1764
else if (log2ElementBytes == 2)
1767
(pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->slice & 1) << 3);
1768
microBlockOffset = (microBlockOffset << 2) | ((pIn->y & 2) << 5);
1772
zh = pIn->slice >> 1;
1774
else if (log2ElementBytes == 3)
1777
(pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2) | ((pIn->x & 2) << 2);
1778
microBlockOffset <<= 3;
1782
zh = pIn->slice >> 1;
1787
(((pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2)) << 4);
1791
zh = pIn->slice >> 1;
1794
microBlockOffset |= ((MortonGen3d(xh, yh, zh, 1) << 7) & 0x380);
1797
return microBlockOffset;
1801
************************************************************************************************************************
1802
* Lib::GetPipeXorBits
1805
* Internal function to get bits number for pipe/se xor operation
1809
************************************************************************************************************************
1811
UINT_32 Lib::GetPipeXorBits(
1812
UINT_32 macroBlockBits) const
1814
ADDR_ASSERT(macroBlockBits >= m_pipeInterleaveLog2);
1816
// Total available xor bits
1817
UINT_32 xorBits = macroBlockBits - m_pipeInterleaveLog2;
1820
UINT_32 pipeBits = Min(xorBits, m_pipesLog2 + m_seLog2);
1826
************************************************************************************************************************
1827
* Lib::Addr2GetPreferredSurfaceSetting
1830
* Internal function to get suggested surface information for cliet to use
1834
************************************************************************************************************************
1836
ADDR_E_RETURNCODE Lib::Addr2GetPreferredSurfaceSetting(
1837
const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
1838
ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const
1840
ADDR_E_RETURNCODE returnCode;
1842
if ((GetFillSizeFieldsFlags() == TRUE) &&
1843
((pIn->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT)) ||
1844
(pOut->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT))))
1846
returnCode = ADDR_INVALIDPARAMS;
1850
returnCode = HwlGetPreferredSurfaceSetting(pIn, pOut);
1857
************************************************************************************************************************
1858
* Lib::ComputeBlock256Equation
1861
* Compute equation for block 256B
1864
* If equation computed successfully
1866
************************************************************************************************************************
1868
ADDR_E_RETURNCODE Lib::ComputeBlock256Equation(
1869
AddrResourceType rsrcType,
1870
AddrSwizzleMode swMode,
1871
UINT_32 elementBytesLog2,
1872
ADDR_EQUATION* pEquation) const
1874
ADDR_E_RETURNCODE ret;
1876
if (IsBlock256b(swMode))
1878
ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation);
1882
ADDR_ASSERT_ALWAYS();
1883
ret = ADDR_INVALIDPARAMS;
1890
************************************************************************************************************************
1891
* Lib::ComputeThinEquation
1894
* Compute equation for 2D/3D resource which use THIN mode
1897
* If equation computed successfully
1899
************************************************************************************************************************
1901
ADDR_E_RETURNCODE Lib::ComputeThinEquation(
1902
AddrResourceType rsrcType,
1903
AddrSwizzleMode swMode,
1904
UINT_32 elementBytesLog2,
1905
ADDR_EQUATION* pEquation) const
1907
ADDR_E_RETURNCODE ret;
1909
if (IsThin(rsrcType, swMode))
1911
ret = HwlComputeThinEquation(rsrcType, swMode, elementBytesLog2, pEquation);
1915
ADDR_ASSERT_ALWAYS();
1916
ret = ADDR_INVALIDPARAMS;
1923
************************************************************************************************************************
1924
* Lib::ComputeThickEquation
1927
* Compute equation for 3D resource which use THICK mode
1930
* If equation computed successfully
1932
************************************************************************************************************************
1934
ADDR_E_RETURNCODE Lib::ComputeThickEquation(
1935
AddrResourceType rsrcType,
1936
AddrSwizzleMode swMode,
1937
UINT_32 elementBytesLog2,
1938
ADDR_EQUATION* pEquation) const
1940
ADDR_E_RETURNCODE ret;
1942
if (IsThick(rsrcType, swMode))
1944
ret = HwlComputeThickEquation(rsrcType, swMode, elementBytesLog2, pEquation);
1948
ADDR_ASSERT_ALWAYS();
1949
ret = ADDR_INVALIDPARAMS;
1956
************************************************************************************************************************
1957
* Lib::ComputeQbStereoInfo
1960
* Get quad buffer stereo information
1963
************************************************************************************************************************
1965
VOID Lib::ComputeQbStereoInfo(
1966
ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] updated pOut+pStereoInfo
1969
ADDR_ASSERT(pOut->bpp >= 8);
1970
ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
1972
// Save original height
1973
pOut->pStereoInfo->eyeHeight = pOut->height;
1976
pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
1981
ADDR_ASSERT(pOut->height <= MaxSurfaceHeight);
1983
pOut->pixelHeight <<= 1;
1986
pOut->surfSize <<= 1;
1987
pOut->sliceSize <<= 1;
1991
************************************************************************************************************************
1992
* Lib::FilterInvalidEqSwizzleMode
1995
* Filter out swizzle mode(s) if it doesn't have valid equation index
1999
************************************************************************************************************************
2001
VOID Lib::FilterInvalidEqSwizzleMode(
2002
ADDR2_SWMODE_SET& allowedSwModeSet,
2003
AddrResourceType resourceType,
2007
if (resourceType != ADDR_RSRC_TEX_1D)
2009
UINT_32 allowedSwModeSetVal = allowedSwModeSet.value;
2010
const UINT_32 rsrcTypeIdx = static_cast<UINT_32>(resourceType) - 1;
2011
UINT_32 validSwModeSet = allowedSwModeSetVal;
2013
for (UINT_32 swModeIdx = 1; validSwModeSet != 0; swModeIdx++)
2015
if (validSwModeSet & 1)
2017
if (m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2] == ADDR_INVALID_EQUATION_INDEX)
2019
allowedSwModeSetVal &= ~(1u << swModeIdx);
2023
validSwModeSet >>= 1;
2026
// Only apply the filtering if at least one valid swizzle mode remains
2027
if (allowedSwModeSetVal != 0)
2029
allowedSwModeSet.value = allowedSwModeSetVal;
2035
************************************************************************************************************************
2036
* Lib::IsBlockTypeAvaiable
2039
* Determine whether a block type is allowed in a given blockSet
2043
************************************************************************************************************************
2045
BOOL_32 Lib::IsBlockTypeAvaiable(
2046
ADDR2_BLOCK_SET blockSet,
2047
AddrBlockType blockType)
2051
if (blockType == AddrBlockLinear)
2053
avail = blockSet.linear ? TRUE : FALSE;
2057
avail = blockSet.value & (1 << (static_cast<UINT_32>(blockType) - 1)) ? TRUE : FALSE;
2064
************************************************************************************************************************
2065
* Lib::BlockTypeWithinMemoryBudget
2068
* Determine whether a new block type is acceptible based on memory waste ratio
2072
************************************************************************************************************************
2074
BOOL_32 Lib::BlockTypeWithinMemoryBudget(
2076
UINT_64 newBlockTypeSize,
2079
DOUBLE memoryBudget,
2080
BOOL_32 newBlockTypeBigger)
2082
BOOL_32 accept = FALSE;
2084
if (memoryBudget >= 1.0)
2086
if (newBlockTypeBigger)
2088
if ((static_cast<DOUBLE>(newBlockTypeSize) / minSize) <= memoryBudget)
2095
if ((static_cast<DOUBLE>(minSize) / newBlockTypeSize) > memoryBudget)
2103
if (newBlockTypeBigger)
2105
if ((newBlockTypeSize * ratioHi) <= (minSize * ratioLow))
2112
if ((newBlockTypeSize * ratioLow) < (minSize * ratioHi))
2124
************************************************************************************************************************
2125
* Lib::ValidateStereoInfo
2128
* Validate stereo info by checking a few typical cases
2132
************************************************************************************************************************
2134
VOID Lib::ValidateStereoInfo(
2135
const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
2136
const ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in] output structure
2139
ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT addrIn = {};
2140
addrIn.size = sizeof(addrIn);
2141
addrIn.swizzleMode = pIn->swizzleMode;
2142
addrIn.flags = pIn->flags;
2143
addrIn.flags.qbStereo = 0;
2144
addrIn.resourceType = pIn->resourceType;
2145
addrIn.bpp = pIn->bpp;
2146
addrIn.unalignedWidth = pIn->width;
2147
addrIn.numSlices = pIn->numSlices;
2148
addrIn.numMipLevels = pIn->numMipLevels;
2149
addrIn.numSamples = pIn->numSamples;
2150
addrIn.numFrags = pIn->numFrags;
2152
// Call Addr2ComputePipeBankXor() and validate different pbXor value if necessary...
2153
const UINT_32 pbXor = 0;
2155
ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT addrOut = {};
2156
addrOut.size = sizeof(addrOut);
2158
// Make the array to be {0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096} for full test
2159
const UINT_32 TestCoord[] = {0};
2161
for (UINT_32 xIdx = 0; xIdx < sizeof(TestCoord) / sizeof(TestCoord[0]); xIdx++)
2163
if (TestCoord[xIdx] < pIn->width)
2165
addrIn.x = TestCoord[xIdx];
2167
for (UINT_32 yIdx = 0; yIdx < sizeof(TestCoord) / sizeof(TestCoord[0]); yIdx++)
2169
if (TestCoord[yIdx] < pIn->height)
2171
addrIn.y = TestCoord[yIdx] + pOut->pStereoInfo->eyeHeight;
2172
addrIn.pipeBankXor = pbXor ^ pOut->pStereoInfo->rightSwizzle;
2173
addrIn.unalignedHeight = pIn->height + pOut->pStereoInfo->eyeHeight;
2175
ADDR_E_RETURNCODE ret = ComputeSurfaceAddrFromCoord(&addrIn, &addrOut);
2176
ADDR_ASSERT(ret == ADDR_OK);
2178
const UINT_64 rightEyeOffsetFromBase = addrOut.addr;
2180
addrIn.y = TestCoord[yIdx];
2181
addrIn.pipeBankXor = pbXor;
2182
addrIn.unalignedHeight = pIn->height;
2184
ret = ComputeSurfaceAddrFromCoord(&addrIn, &addrOut);
2185
ADDR_ASSERT(ret == ADDR_OK);
2187
const UINT_64 rightEyeOffsetRelative = addrOut.addr;
2189
ADDR_ASSERT(rightEyeOffsetFromBase == rightEyeOffsetRelative + pOut->pStereoInfo->rightOffset);