• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ************************************************************************************************************************
3 *
4 *  Copyright (C) 2007-2022 Advanced Micro Devices, Inc.  All rights reserved.
5 *  SPDX-License-Identifier: MIT
6 *
7 ***********************************************************************************************************************/
8 
9 /**
10 ************************************************************************************************************************
11 * @file  gfx11addrlib.cpp
12 * @brief Contain the implementation for the Gfx11Lib class.
13 ************************************************************************************************************************
14 */
15 
16 #include "gfx11addrlib.h"
17 #include "gfx11_gb_reg.h"
18 
19 #include "amdgpu_asic_addr.h"
20 
21 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
22 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
23 
24 namespace Addr
25 {
26 /**
27 ************************************************************************************************************************
28 *   Gfx11HwlInit
29 *
30 *   @brief
31 *       Creates an Gfx11Lib object.
32 *
33 *   @return
34 *       Returns an Gfx11Lib object pointer.
35 ************************************************************************************************************************
36 */
Gfx11HwlInit(const Client * pClient)37 Addr::Lib* Gfx11HwlInit(const Client* pClient)
38 {
39     return V2::Gfx11Lib::CreateObj(pClient);
40 }
41 
42 namespace V2
43 {
44 
45 ////////////////////////////////////////////////////////////////////////////////////////////////////
46 //                               Static Const Member
47 ////////////////////////////////////////////////////////////////////////////////////////////////////
48 
49 const SwizzleModeFlags Gfx11Lib::SwizzleModeTable[ADDR_SW_MAX_TYPE] =
50 {//Linear 256B  4KB  64KB  256KB   Z    Std   Disp  Rot   XOR    T     RtOpt Reserved
51     {{1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_LINEAR
52     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
53     {{0,    1,    0,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_256B_D
54     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
55 
56     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
57     {{0,    0,    1,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_4KB_S
58     {{0,    0,    1,    0,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_4KB_D
59     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
60 
61     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
62     {{0,    0,    0,    1,    0,    0,    1,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_64KB_S
63     {{0,    0,    0,    1,    0,    0,    0,    1,    0,    0,    0,    0,    0}}, // ADDR_SW_64KB_D
64     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
65 
66     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
67     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
68     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
69     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
70 
71     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
72     {{0,    0,    0,    1,    0,    0,    1,    0,    0,    1,    1,    0,    0}}, // ADDR_SW_64KB_S_T
73     {{0,    0,    0,    1,    0,    0,    0,    1,    0,    1,    1,    0,    0}}, // ADDR_SW_64KB_D_T
74     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
75 
76     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
77     {{0,    0,    1,    0,    0,    0,    1,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_4KB_S_X
78     {{0,    0,    1,    0,    0,    0,    0,    1,    0,    1,    0,    0,    0}}, // ADDR_SW_4KB_D_X
79     {{0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // Reserved
80 
81     {{0,    0,    0,    1,    0,    1,    0,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_Z_X
82     {{0,    0,    0,    1,    0,    0,    1,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_S_X
83     {{0,    0,    0,    1,    0,    0,    0,    1,    0,    1,    0,    0,    0}}, // ADDR_SW_64KB_D_X
84     {{0,    0,    0,    1,    0,    0,    0,    0,    0,    1,    0,    1,    0}}, // ADDR_SW_64KB_R_X
85 
86     {{0,    0,    0,    0,    1,    1,    0,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_256KB_Z_X
87     {{0,    0,    0,    0,    1,    0,    1,    0,    0,    1,    0,    0,    0}}, // ADDR_SW_256KB_S_X
88     {{0,    0,    0,    0,    1,    0,    0,    1,    0,    1,    0,    0,    0}}, // ADDR_SW_256KB_D_X
89     {{0,    0,    0,    0,    1,    0,    0,    0,    0,    1,    0,    1,    0}}, // ADDR_SW_256KB_R_X
90     {{1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0}}, // ADDR_SW_LINEAR_GENERAL
91 };
92 
93 const Dim3d Gfx11Lib::Block256_3d[] = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}};
94 
95 const Dim3d Gfx11Lib::Block256K_Log2_3d[] = {{6, 6, 6}, {5, 6, 6}, {5, 6, 5}, {5, 5, 5}, {4, 5, 5}};
96 const Dim3d Gfx11Lib::Block64K_Log2_3d[]  = {{6, 5, 5}, {5, 5, 5}, {5, 5, 4}, {5, 4, 4}, {4, 4, 4}};
97 const Dim3d Gfx11Lib::Block4K_Log2_3d[]   = {{4, 4, 4}, {3, 4, 4}, {3, 4, 3}, {3, 3, 3}, {2, 3, 3}};
98 
99 /**
100 ************************************************************************************************************************
101 *   Gfx11Lib::Gfx11Lib
102 *
103 *   @brief
104 *       Constructor
105 *
106 ************************************************************************************************************************
107 */
Gfx11Lib(const Client * pClient)108 Gfx11Lib::Gfx11Lib(const Client* pClient)
109     :
110     Lib(pClient),
111     m_numPkrLog2(0),
112     m_numSaLog2(0),
113     m_colorBaseIndex(0),
114     m_htileBaseIndex(0),
115     m_dccBaseIndex(0)
116 {
117     memset(&m_settings, 0, sizeof(m_settings));
118     memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable));
119 }
120 
121 /**
122 ************************************************************************************************************************
123 *   Gfx11Lib::~Gfx11Lib
124 *
125 *   @brief
126 *       Destructor
127 ************************************************************************************************************************
128 */
~Gfx11Lib()129 Gfx11Lib::~Gfx11Lib()
130 {
131 }
132 
133 /**
134 ************************************************************************************************************************
135 *   Gfx11Lib::HwlComputeHtileInfo
136 *
137 *   @brief
138 *       Interface function stub of AddrComputeHtilenfo
139 *
140 *   @return
141 *       ADDR_E_RETURNCODE
142 ************************************************************************************************************************
143 */
HwlComputeHtileInfo(const ADDR2_COMPUTE_HTILE_INFO_INPUT * pIn,ADDR2_COMPUTE_HTILE_INFO_OUTPUT * pOut) const144 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeHtileInfo(
145     const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn,    ///< [in] input structure
146     ADDR2_COMPUTE_HTILE_INFO_OUTPUT*      pOut    ///< [out] output structure
147     ) const
148 {
149     ADDR_E_RETURNCODE ret = ADDR_OK;
150 
151     if ((pIn->swizzleMode != ADDR_SW_64KB_Z_X)  &&
152         (pIn->swizzleMode != ADDR_SW_256KB_Z_X) &&
153         (pIn->hTileFlags.pipeAligned != TRUE))
154     {
155         ret = ADDR_INVALIDPARAMS;
156     }
157     else
158     {
159         Dim3d         metaBlk     = {};
160         const UINT_32 metaBlkSize = GetMetaBlkSize(Gfx11DataDepthStencil,
161                                                    ADDR_RSRC_TEX_2D,
162                                                    pIn->swizzleMode,
163                                                    0,
164                                                    0,
165                                                    TRUE,
166                                                    &metaBlk);
167 
168         pOut->pitch         = PowTwoAlign(pIn->unalignedWidth,  metaBlk.w);
169         pOut->height        = PowTwoAlign(pIn->unalignedHeight, metaBlk.h);
170         pOut->baseAlign     = Max(metaBlkSize, 1u << (m_pipesLog2 + 11u));
171         pOut->metaBlkWidth  = metaBlk.w;
172         pOut->metaBlkHeight = metaBlk.h;
173 
174         if (pIn->numMipLevels > 1)
175         {
176             ADDR_ASSERT(pIn->firstMipIdInTail <= pIn->numMipLevels);
177 
178             UINT_32 offset = (pIn->firstMipIdInTail == pIn->numMipLevels) ? 0 : metaBlkSize;
179 
180             for (INT_32 i = static_cast<INT_32>(pIn->firstMipIdInTail) - 1; i >=0; i--)
181             {
182                 UINT_32 mipWidth, mipHeight;
183 
184                 GetMipSize(pIn->unalignedWidth, pIn->unalignedHeight, 1, i, &mipWidth, &mipHeight);
185 
186                 mipWidth  = PowTwoAlign(mipWidth,  metaBlk.w);
187                 mipHeight = PowTwoAlign(mipHeight, metaBlk.h);
188 
189                 const UINT_32 pitchInM     = mipWidth  / metaBlk.w;
190                 const UINT_32 heightInM    = mipHeight / metaBlk.h;
191                 const UINT_32 mipSliceSize = pitchInM * heightInM * metaBlkSize;
192 
193                 if (pOut->pMipInfo != NULL)
194                 {
195                     pOut->pMipInfo[i].inMiptail = FALSE;
196                     pOut->pMipInfo[i].offset    = offset;
197                     pOut->pMipInfo[i].sliceSize = mipSliceSize;
198                 }
199 
200                 offset += mipSliceSize;
201             }
202 
203             pOut->sliceSize          = offset;
204             pOut->metaBlkNumPerSlice = offset / metaBlkSize;
205             pOut->htileBytes         = pOut->sliceSize * pIn->numSlices;
206 
207             if (pOut->pMipInfo != NULL)
208             {
209                 for (UINT_32 i = pIn->firstMipIdInTail; i < pIn->numMipLevels; i++)
210                 {
211                     pOut->pMipInfo[i].inMiptail = TRUE;
212                     pOut->pMipInfo[i].offset    = 0;
213                     pOut->pMipInfo[i].sliceSize = 0;
214                 }
215 
216                 if (pIn->firstMipIdInTail != pIn->numMipLevels)
217                 {
218                     pOut->pMipInfo[pIn->firstMipIdInTail].sliceSize = metaBlkSize;
219                 }
220             }
221         }
222         else
223         {
224             const UINT_32 pitchInM  = pOut->pitch  / metaBlk.w;
225             const UINT_32 heightInM = pOut->height / metaBlk.h;
226 
227             pOut->metaBlkNumPerSlice    = pitchInM * heightInM;
228             pOut->sliceSize             = pOut->metaBlkNumPerSlice * metaBlkSize;
229             pOut->htileBytes            = pOut->sliceSize * pIn->numSlices;
230 
231             if (pOut->pMipInfo != NULL)
232             {
233                 pOut->pMipInfo[0].inMiptail = FALSE;
234                 pOut->pMipInfo[0].offset    = 0;
235                 pOut->pMipInfo[0].sliceSize = pOut->sliceSize;
236             }
237         }
238 
239         // Get the HTILE address equation (copied from HtileAddrFromCoord).
240         // HTILE addressing depends on the number of samples, but this code doesn't support it yet.
241         const UINT_32  index         = m_htileBaseIndex;
242         const UINT_8* patIdxTable = GFX11_HTILE_PATIDX;
243 
244         ADDR_C_ASSERT(sizeof(GFX11_HTILE_SW_PATTERN[patIdxTable[index]]) == 72 * 2);
245         pOut->equation.gfx10_bits = (UINT_16 *)GFX11_HTILE_SW_PATTERN[patIdxTable[index]];
246     }
247 
248     return ret;
249 }
250 
251 /**
252 ************************************************************************************************************************
253 *   Gfx11Lib::HwlComputeDccInfo
254 *
255 *   @brief
256 *       Interface function to compute DCC key info
257 *
258 *   @return
259 *       ADDR_E_RETURNCODE
260 ************************************************************************************************************************
261 */
HwlComputeDccInfo(const ADDR2_COMPUTE_DCCINFO_INPUT * pIn,ADDR2_COMPUTE_DCCINFO_OUTPUT * pOut) const262 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeDccInfo(
263     const ADDR2_COMPUTE_DCCINFO_INPUT* pIn,    ///< [in] input structure
264     ADDR2_COMPUTE_DCCINFO_OUTPUT*      pOut    ///< [out] output structure
265     ) const
266 {
267     ADDR_E_RETURNCODE ret = ADDR_OK;
268 
269     if (IsLinear(pIn->swizzleMode) || IsBlock256b(pIn->swizzleMode))
270     {
271         ret = ADDR_INVALIDPARAMS;
272     }
273     else
274     {
275         const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);
276         const UINT_32 numFragLog2 = Log2(Max(pIn->numFrags, 1u));
277         Dim3d         compBlock   = {};
278 
279         GetCompressedBlockSizeLog2(Gfx11DataColor,
280                                    pIn->resourceType,
281                                    pIn->swizzleMode,
282                                    elemLog2,
283                                    numFragLog2,
284                                    &compBlock);
285         pOut->compressBlkWidth  = 1 << compBlock.w;
286         pOut->compressBlkHeight = 1 << compBlock.h;
287         pOut->compressBlkDepth  = 1 << compBlock.d;
288 
289         if (ret == ADDR_OK)
290         {
291             Dim3d         metaBlk     = {};
292             const UINT_32 metaBlkSize = GetMetaBlkSize(Gfx11DataColor,
293                                                        pIn->resourceType,
294                                                        pIn->swizzleMode,
295                                                        elemLog2,
296                                                        numFragLog2,
297                                                        pIn->dccKeyFlags.pipeAligned,
298                                                        &metaBlk);
299 
300             pOut->dccRamBaseAlign   = metaBlkSize;
301             pOut->metaBlkWidth      = metaBlk.w;
302             pOut->metaBlkHeight     = metaBlk.h;
303             pOut->metaBlkDepth      = metaBlk.d;
304             pOut->metaBlkSize       = metaBlkSize;
305 
306             pOut->pitch             = PowTwoAlign(pIn->unalignedWidth,     metaBlk.w);
307             pOut->height            = PowTwoAlign(pIn->unalignedHeight,    metaBlk.h);
308             pOut->depth             = PowTwoAlign(Max(pIn->numSlices, 1u), metaBlk.d);
309 
310             if (pIn->numMipLevels > 1)
311             {
312                 ADDR_ASSERT(pIn->firstMipIdInTail <= pIn->numMipLevels);
313 
314                 UINT_32 offset = (pIn->firstMipIdInTail == pIn->numMipLevels) ? 0 : metaBlkSize;
315 
316                 for (INT_32 i = static_cast<INT_32>(pIn->firstMipIdInTail) - 1; i >= 0; i--)
317                 {
318                     UINT_32 mipWidth, mipHeight;
319 
320                     GetMipSize(pIn->unalignedWidth, pIn->unalignedHeight, 1, i, &mipWidth, &mipHeight);
321 
322                     mipWidth  = PowTwoAlign(mipWidth,  metaBlk.w);
323                     mipHeight = PowTwoAlign(mipHeight, metaBlk.h);
324 
325                     const UINT_32 pitchInM     = mipWidth  / metaBlk.w;
326                     const UINT_32 heightInM    = mipHeight / metaBlk.h;
327                     const UINT_32 mipSliceSize = pitchInM * heightInM * metaBlkSize;
328 
329                     if (pOut->pMipInfo != NULL)
330                     {
331                         pOut->pMipInfo[i].inMiptail = FALSE;
332                         pOut->pMipInfo[i].offset    = offset;
333                         pOut->pMipInfo[i].sliceSize = mipSliceSize;
334                     }
335 
336                     offset += mipSliceSize;
337                 }
338 
339                 pOut->dccRamSliceSize    = offset;
340                 pOut->metaBlkNumPerSlice = offset / metaBlkSize;
341                 pOut->dccRamSize         = pOut->dccRamSliceSize * (pOut->depth  / metaBlk.d);
342 
343                 if (pOut->pMipInfo != NULL)
344                 {
345                     for (UINT_32 i = pIn->firstMipIdInTail; i < pIn->numMipLevels; i++)
346                     {
347                         pOut->pMipInfo[i].inMiptail = TRUE;
348                         pOut->pMipInfo[i].offset    = 0;
349                         pOut->pMipInfo[i].sliceSize = 0;
350                     }
351 
352                     if (pIn->firstMipIdInTail != pIn->numMipLevels)
353                     {
354                         pOut->pMipInfo[pIn->firstMipIdInTail].sliceSize = metaBlkSize;
355                     }
356                 }
357             }
358             else
359             {
360                 const UINT_32 pitchInM  = pOut->pitch  / metaBlk.w;
361                 const UINT_32 heightInM = pOut->height / metaBlk.h;
362 
363                 pOut->metaBlkNumPerSlice = pitchInM * heightInM;
364                 pOut->dccRamSliceSize    = pOut->metaBlkNumPerSlice * metaBlkSize;
365                 pOut->dccRamSize         = pOut->dccRamSliceSize * (pOut->depth  / metaBlk.d);
366 
367                 if (pOut->pMipInfo != NULL)
368                 {
369                     pOut->pMipInfo[0].inMiptail = FALSE;
370                     pOut->pMipInfo[0].offset    = 0;
371                     pOut->pMipInfo[0].sliceSize = pOut->dccRamSliceSize;
372                 }
373             }
374 
375             // Get the DCC address equation (copied from DccAddrFromCoord)
376             const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);
377             const UINT_32 numPipeLog2 = m_pipesLog2;
378             UINT_32       index       = m_dccBaseIndex + elemLog2;
379             const UINT_8* patIdxTable = (pIn->swizzleMode == ADDR_SW_64KB_R_X) ?
380                                         GFX11_DCC_64K_R_X_PATIDX : GFX11_DCC_256K_R_X_PATIDX;
381 
382             if (pIn->dccKeyFlags.pipeAligned)
383             {
384                 index += MaxNumOfBpp;
385 
386                 if (m_numPkrLog2 < 2)
387                 {
388                     index += m_pipesLog2 * MaxNumOfBpp;
389                 }
390                 else
391                 {
392                     // 4 groups for "m_numPkrLog2 < 2" case
393                     index += 4 * MaxNumOfBpp;
394 
395                     const UINT_32 dccPipePerPkr = 3;
396 
397                     index += (m_numPkrLog2 - 2) * dccPipePerPkr * MaxNumOfBpp +
398                              (m_pipesLog2 - m_numPkrLog2) * MaxNumOfBpp;
399                 }
400             }
401 
402             ADDR_C_ASSERT(sizeof(GFX11_DCC_R_X_SW_PATTERN[patIdxTable[index]]) == 68 * 2);
403             pOut->equation.gfx10_bits = (UINT_16*)GFX11_DCC_R_X_SW_PATTERN[patIdxTable[index]];
404         }
405     }
406 
407     return ret;
408 }
409 
410 /**
411 ************************************************************************************************************************
412 *   Gfx11Lib::HwlComputeHtileAddrFromCoord
413 *
414 *   @brief
415 *       Interface function stub of AddrComputeHtileAddrFromCoord
416 *
417 *   @return
418 *       ADDR_E_RETURNCODE
419 ************************************************************************************************************************
420 */
HwlComputeHtileAddrFromCoord(const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT * pOut)421 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeHtileAddrFromCoord(
422     const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
423     ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT*      pOut)   ///< [out] output structure
424 {
425     ADDR_E_RETURNCODE returnCode = ADDR_OK;
426 
427     if (pIn->numMipLevels > 1)
428     {
429         returnCode = ADDR_NOTIMPLEMENTED;
430     }
431     else
432     {
433         ADDR2_COMPUTE_HTILE_INFO_INPUT input = {};
434         input.size            = sizeof(input);
435         input.hTileFlags      = pIn->hTileFlags;
436         input.depthFlags      = pIn->depthflags;
437         input.swizzleMode     = pIn->swizzleMode;
438         input.unalignedWidth  = Max(pIn->unalignedWidth,  1u);
439         input.unalignedHeight = Max(pIn->unalignedHeight, 1u);
440         input.numSlices       = Max(pIn->numSlices,       1u);
441         input.numMipLevels    = 1;
442 
443         ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {};
444         output.size = sizeof(output);
445 
446         returnCode = ComputeHtileInfo(&input, &output);
447 
448         if (returnCode == ADDR_OK)
449         {
450             const UINT_32  numSampleLog2 = Log2(pIn->numSamples);
451             const UINT_32  pipeMask      = (1 << m_pipesLog2) - 1;
452             const UINT_32  index         = m_htileBaseIndex + numSampleLog2;
453             const UINT_8*  patIdxTable   = GFX11_HTILE_PATIDX;
454             const UINT_32  blkSizeLog2   = Log2(output.metaBlkWidth) + Log2(output.metaBlkHeight) - 4;
455             const UINT_32  blkMask       = (1 << blkSizeLog2) - 1;
456             const UINT_32  blkOffset     = ComputeOffsetFromSwizzlePattern(GFX11_HTILE_SW_PATTERN[patIdxTable[index]],
457                                                                            blkSizeLog2 + 1, // +1 for nibble offset
458                                                                            pIn->x,
459                                                                            pIn->y,
460                                                                            pIn->slice,
461                                                                            0);
462             const UINT_32 xb       = pIn->x / output.metaBlkWidth;
463             const UINT_32 yb       = pIn->y / output.metaBlkHeight;
464             const UINT_32 pb       = output.pitch / output.metaBlkWidth;
465             const UINT_32 blkIndex = (yb * pb) + xb;
466             const UINT_32 pipeXor  = ((pIn->pipeXor & pipeMask) << m_pipeInterleaveLog2) & blkMask;
467 
468             pOut->addr = (static_cast<UINT_64>(output.sliceSize) * pIn->slice) +
469                          (blkIndex * (1 << blkSizeLog2)) +
470                          ((blkOffset >> 1) ^ pipeXor);
471         }
472     }
473 
474     return returnCode;
475 }
476 
477 /**
478 ************************************************************************************************************************
479 *   Gfx11Lib::HwlComputeHtileCoordFromAddr
480 *
481 *   @brief
482 *       Interface function stub of AddrComputeHtileCoordFromAddr
483 *
484 *   @return
485 *       ADDR_E_RETURNCODE
486 ************************************************************************************************************************
487 */
HwlComputeHtileCoordFromAddr(const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT * pOut)488 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeHtileCoordFromAddr(
489     const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn,    ///< [in] input structure
490     ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT*      pOut)   ///< [out] output structure
491 {
492     ADDR_NOT_IMPLEMENTED();
493 
494     return ADDR_OK;
495 }
496 
497 /**
498 ************************************************************************************************************************
499 *   Gfx11Lib::HwlSupportComputeDccAddrFromCoord
500 *
501 *   @brief
502 *       Check whether HwlComputeDccAddrFromCoord() can be done for the input parameter
503 *
504 *   @return
505 *       ADDR_E_RETURNCODE
506 ************************************************************************************************************************
507 */
HwlSupportComputeDccAddrFromCoord(const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT * pIn)508 ADDR_E_RETURNCODE Gfx11Lib::HwlSupportComputeDccAddrFromCoord(
509     const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn)
510 {
511     ADDR_E_RETURNCODE returnCode = ADDR_OK;
512 
513     if ((pIn->resourceType != ADDR_RSRC_TEX_2D) ||
514         ((pIn->swizzleMode != ADDR_SW_64KB_R_X) &&
515          (pIn->swizzleMode != ADDR_SW_256KB_R_X)) ||
516         (pIn->dccKeyFlags.linear == TRUE) ||
517         (pIn->numFrags > 1) ||
518         (pIn->numMipLevels > 1) ||
519         (pIn->mipId > 0))
520     {
521         returnCode = ADDR_NOTSUPPORTED;
522     }
523     else if ((pIn->pitch == 0)         ||
524              (pIn->metaBlkWidth == 0)  ||
525              (pIn->metaBlkHeight == 0) ||
526              (pIn->slice > 0 && pIn->dccRamSliceSize == 0))
527     {
528         returnCode = ADDR_NOTSUPPORTED;
529     }
530 
531     return returnCode;
532 }
533 
534 /**
535 ************************************************************************************************************************
536 *   Gfx11Lib::HwlComputeDccAddrFromCoord
537 *
538 *   @brief
539 *       Interface function stub of AddrComputeDccAddrFromCoord
540 *
541 *   @return
542 *       N/A
543 ************************************************************************************************************************
544 */
HwlComputeDccAddrFromCoord(const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT * pOut)545 VOID Gfx11Lib::HwlComputeDccAddrFromCoord(
546     const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn,  ///< [in] input structure
547     ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT*      pOut) ///< [out] output structure
548 {
549     const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);
550     const UINT_32 numPipeLog2 = m_pipesLog2;
551     const UINT_32 pipeMask    = (1 << numPipeLog2) - 1;
552     UINT_32       index       = m_dccBaseIndex + elemLog2;
553     const UINT_8* patIdxTable = (pIn->swizzleMode == ADDR_SW_64KB_R_X) ?
554                                 GFX11_DCC_64K_R_X_PATIDX : GFX11_DCC_256K_R_X_PATIDX;
555 
556     if (pIn->dccKeyFlags.pipeAligned)
557     {
558         index += MaxNumOfBpp;
559 
560         if (m_numPkrLog2 < 2)
561         {
562             index += m_pipesLog2 * MaxNumOfBpp;
563         }
564         else
565         {
566             // 4 groups for "m_numPkrLog2 < 2" case
567             index += 4 * MaxNumOfBpp;
568 
569             const UINT_32 dccPipePerPkr = 3;
570 
571             index += (m_numPkrLog2 - 2) * dccPipePerPkr * MaxNumOfBpp +
572                      (m_pipesLog2 - m_numPkrLog2) * MaxNumOfBpp;
573         }
574     }
575 
576     const UINT_32  blkSizeLog2 = Log2(pIn->metaBlkWidth) + Log2(pIn->metaBlkHeight) + elemLog2 - 8;
577     const UINT_32  blkMask     = (1 << blkSizeLog2) - 1;
578     const UINT_32  blkOffset   = ComputeOffsetFromSwizzlePattern(GFX11_DCC_R_X_SW_PATTERN[patIdxTable[index]],
579                                                                  blkSizeLog2 + 1, // +1 for nibble offset
580                                                                  pIn->x,
581                                                                  pIn->y,
582                                                                  pIn->slice,
583                                                                  0);
584     const UINT_32 xb       = pIn->x / pIn->metaBlkWidth;
585     const UINT_32 yb       = pIn->y / pIn->metaBlkHeight;
586     const UINT_32 pb       = pIn->pitch / pIn->metaBlkWidth;
587     const UINT_32 blkIndex = (yb * pb) + xb;
588     const UINT_32 pipeXor  = ((pIn->pipeXor & pipeMask) << m_pipeInterleaveLog2) & blkMask;
589 
590     pOut->addr = (static_cast<UINT_64>(pIn->dccRamSliceSize) * pIn->slice) +
591                  (blkIndex * (1 << blkSizeLog2)) +
592                  ((blkOffset >> 1) ^ pipeXor);
593 }
594 
595 /**
596 ************************************************************************************************************************
597 *   Gfx11Lib::HwlInitGlobalParams
598 *
599 *   @brief
600 *       Initializes global parameters
601 *
602 *   @return
603 *       TRUE if all settings are valid
604 *
605 ************************************************************************************************************************
606 */
HwlInitGlobalParams(const ADDR_CREATE_INPUT * pCreateIn)607 BOOL_32 Gfx11Lib::HwlInitGlobalParams(
608     const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
609 {
610     BOOL_32              valid = TRUE;
611     GB_ADDR_CONFIG_GFX11 gbAddrConfig;
612 
613     gbAddrConfig.u32All = pCreateIn->regValue.gbAddrConfig;
614 
615     switch (gbAddrConfig.bits.NUM_PIPES)
616     {
617         case ADDR_CONFIG_1_PIPE:
618             m_pipes     = 1;
619             m_pipesLog2 = 0;
620             break;
621         case ADDR_CONFIG_2_PIPE:
622             m_pipes     = 2;
623             m_pipesLog2 = 1;
624             break;
625         case ADDR_CONFIG_4_PIPE:
626             m_pipes     = 4;
627             m_pipesLog2 = 2;
628             break;
629         case ADDR_CONFIG_8_PIPE:
630             m_pipes     = 8;
631             m_pipesLog2 = 3;
632             break;
633         case ADDR_CONFIG_16_PIPE:
634             m_pipes     = 16;
635             m_pipesLog2 = 4;
636             break;
637         case ADDR_CONFIG_32_PIPE:
638             m_pipes     = 32;
639             m_pipesLog2 = 5;
640             break;
641         case ADDR_CONFIG_64_PIPE:
642             m_pipes     = 64;
643             m_pipesLog2 = 6;
644             break;
645         default:
646             ADDR_ASSERT_ALWAYS();
647             valid = FALSE;
648             break;
649     }
650 
651     switch (gbAddrConfig.bits.PIPE_INTERLEAVE_SIZE)
652     {
653         case ADDR_CONFIG_PIPE_INTERLEAVE_256B:
654             m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B;
655             m_pipeInterleaveLog2  = 8;
656             break;
657         case ADDR_CONFIG_PIPE_INTERLEAVE_512B:
658             m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B;
659             m_pipeInterleaveLog2  = 9;
660             break;
661         case ADDR_CONFIG_PIPE_INTERLEAVE_1KB:
662             m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_1KB;
663             m_pipeInterleaveLog2  = 10;
664             break;
665         case ADDR_CONFIG_PIPE_INTERLEAVE_2KB:
666             m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_2KB;
667             m_pipeInterleaveLog2  = 11;
668             break;
669         default:
670             ADDR_ASSERT_ALWAYS();
671             valid = FALSE;
672             break;
673     }
674 
675     // Addr::V2::Lib::ComputePipeBankXor()/ComputeSlicePipeBankXor() requires pipe interleave to be exactly 8 bits, and
676     // any larger value requires a post-process (left shift) on the output pipeBankXor bits.
677     // And more importantly, SW AddrLib doesn't support sw equation/pattern for PI != 256 case.
678     ADDR_ASSERT(m_pipeInterleaveBytes == ADDR_PIPEINTERLEAVE_256B);
679 
680     // These fields are deprecated on GFX11; they do nothing on HW.
681     m_maxCompFrag     = 1;
682     m_maxCompFragLog2 = 0;
683 
684     // Skip unaligned case
685     m_htileBaseIndex += MaxNumOfAA;
686 
687     m_htileBaseIndex += m_pipesLog2 * MaxNumOfAA;
688     m_colorBaseIndex += m_pipesLog2 * MaxNumOfBpp;
689 
690     m_numPkrLog2 = gbAddrConfig.bits.NUM_PKRS;
691     m_numSaLog2  = (m_numPkrLog2 > 0) ? (m_numPkrLog2 - 1) : 0;
692 
693     ADDR_ASSERT((m_numPkrLog2 <= m_pipesLog2) && ((m_pipesLog2 - m_numPkrLog2) <= 2));
694 
695     if (m_numPkrLog2 >= 2)
696     {
697         m_colorBaseIndex += (2 * m_numPkrLog2 - 2) * MaxNumOfBpp;
698         m_htileBaseIndex += (m_numPkrLog2 - 1) * 3 * MaxNumOfAA;
699     }
700 
701     // There is no so-called VAR swizzle mode on GFX11 and instead there are 4 256KB swizzle modes. Here we treat 256KB
702     // swizzle mode as "VAR" swizzle mode for reusing exising facilities (e.g GetBlockSizeLog2()) provided by base class
703     m_blockVarSizeLog2 = 18;
704 
705     if (valid)
706     {
707         InitEquationTable();
708     }
709 
710     return valid;
711 }
712 
713 /**
714 ************************************************************************************************************************
715 *   Gfx11Lib::HwlConvertChipFamily
716 *
717 *   @brief
718 *       Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
719 *   @return
720 *       ChipFamily
721 ************************************************************************************************************************
722 */
HwlConvertChipFamily(UINT_32 chipFamily,UINT_32 chipRevision)723 ChipFamily Gfx11Lib::HwlConvertChipFamily(
724     UINT_32 chipFamily,        ///< [in] chip family defined in atiih.h
725     UINT_32 chipRevision)      ///< [in] chip revision defined in "asic_family"_id.h
726 {
727     ChipFamily family = ADDR_CHIP_FAMILY_NAVI;
728 
729     switch (chipFamily)
730     {
731         case FAMILY_NV3:
732             if (ASICREV_IS_NAVI31_P(chipRevision))
733             {
734             }
735             if (ASICREV_IS_NAVI32_P(chipRevision))
736             {
737             }
738             if (ASICREV_IS_NAVI33_P(chipRevision))
739             {
740             }
741             break;
742         case FAMILY_GFX1150:
743             if (ASICREV_IS_GFX1150(chipRevision))
744             {
745                 m_settings.isGfx1150 = 1;
746             }
747             break;
748         case FAMILY_GFX1103:
749             m_settings.isGfx1103 = 1;
750             break;
751         default:
752             ADDR_ASSERT(!"Unknown chip family");
753             break;
754     }
755 
756     m_configFlags.use32bppFor422Fmt = TRUE;
757 
758     return family;
759 }
760 
761 /**
762 ************************************************************************************************************************
763 *   Gfx11Lib::GetBlk256SizeLog2
764 *
765 *   @brief
766 *       Get block 256 size
767 *
768 *   @return
769 *       N/A
770 ************************************************************************************************************************
771 */
GetBlk256SizeLog2(AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 elemLog2,UINT_32 numSamplesLog2,Dim3d * pBlock) const772 void Gfx11Lib::GetBlk256SizeLog2(
773     AddrResourceType resourceType,      ///< [in] Resource type
774     AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode
775     UINT_32          elemLog2,          ///< [in] element size log2
776     UINT_32          numSamplesLog2,    ///< [in] number of samples
777     Dim3d*           pBlock             ///< [out] block size
778     ) const
779 {
780     if (IsThin(resourceType, swizzleMode))
781     {
782         UINT_32 blockBits = 8 - elemLog2;
783 
784         // On GFX11, Z and R modes are the same thing.
785         if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))
786         {
787             blockBits -= numSamplesLog2;
788         }
789 
790         pBlock->w = (blockBits >> 1) + (blockBits & 1);
791         pBlock->h = (blockBits >> 1);
792         pBlock->d = 0;
793     }
794     else
795     {
796         ADDR_ASSERT(IsThick(resourceType, swizzleMode));
797 
798         UINT_32 blockBits = 8 - elemLog2;
799 
800         pBlock->d = (blockBits / 3) + (((blockBits % 3) > 0) ? 1 : 0);
801         pBlock->w = (blockBits / 3) + (((blockBits % 3) > 1) ? 1 : 0);
802         pBlock->h = (blockBits / 3);
803     }
804 }
805 
806 /**
807 ************************************************************************************************************************
808 *   Gfx11Lib::GetCompressedBlockSizeLog2
809 *
810 *   @brief
811 *       Get compress block size
812 *
813 *   @return
814 *       N/A
815 ************************************************************************************************************************
816 */
GetCompressedBlockSizeLog2(Gfx11DataType dataType,AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 elemLog2,UINT_32 numSamplesLog2,Dim3d * pBlock) const817 void Gfx11Lib::GetCompressedBlockSizeLog2(
818     Gfx11DataType    dataType,          ///< [in] Data type
819     AddrResourceType resourceType,      ///< [in] Resource type
820     AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode
821     UINT_32          elemLog2,          ///< [in] element size log2
822     UINT_32          numSamplesLog2,    ///< [in] number of samples
823     Dim3d*           pBlock             ///< [out] block size
824     ) const
825 {
826     if (dataType == Gfx11DataColor)
827     {
828         GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, numSamplesLog2, pBlock);
829     }
830     else
831     {
832         ADDR_ASSERT(dataType == Gfx11DataDepthStencil);
833         pBlock->w = 3;
834         pBlock->h = 3;
835         pBlock->d = 0;
836     }
837 }
838 
839 /**
840 ************************************************************************************************************************
841 *   Gfx11Lib::GetMetaOverlapLog2
842 *
843 *   @brief
844 *       Get meta block overlap
845 *
846 *   @return
847 *       N/A
848 ************************************************************************************************************************
849 */
GetMetaOverlapLog2(Gfx11DataType dataType,AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 elemLog2,UINT_32 numSamplesLog2) const850 INT_32 Gfx11Lib::GetMetaOverlapLog2(
851     Gfx11DataType    dataType,          ///< [in] Data type
852     AddrResourceType resourceType,      ///< [in] Resource type
853     AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode
854     UINT_32          elemLog2,          ///< [in] element size log2
855     UINT_32          numSamplesLog2     ///< [in] number of samples
856     ) const
857 {
858     Dim3d compBlock;
859     Dim3d microBlock;
860 
861     GetCompressedBlockSizeLog2(dataType, resourceType, swizzleMode, elemLog2, numSamplesLog2, &compBlock);
862     GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, numSamplesLog2, &microBlock);
863 
864     const INT_32 compSizeLog2   = compBlock.w  + compBlock.h  + compBlock.d;
865     const INT_32 blk256SizeLog2 = microBlock.w + microBlock.h + microBlock.d;
866     const INT_32 maxSizeLog2    = Max(compSizeLog2, blk256SizeLog2);
867     const INT_32 numPipesLog2   = GetEffectiveNumPipes();
868     INT_32       overlap        = numPipesLog2 - maxSizeLog2;
869 
870     if (numPipesLog2 > 1)
871     {
872         overlap++;
873     }
874 
875     // In 16Bpp 8xaa, we lose 1 overlap bit because the block size reduction eats into a pipe anchor bit (y4)
876     if ((elemLog2 == 4) && (numSamplesLog2 == 3))
877     {
878         overlap--;
879     }
880     overlap = Max(overlap, 0);
881     return overlap;
882 }
883 
884 /**
885 ************************************************************************************************************************
886 *   Gfx11Lib::Get3DMetaOverlapLog2
887 *
888 *   @brief
889 *       Get 3d meta block overlap
890 *
891 *   @return
892 *       N/A
893 ************************************************************************************************************************
894 */
Get3DMetaOverlapLog2(AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 elemLog2) const895 INT_32 Gfx11Lib::Get3DMetaOverlapLog2(
896     AddrResourceType resourceType,      ///< [in] Resource type
897     AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode
898     UINT_32          elemLog2           ///< [in] element size log2
899     ) const
900 {
901     Dim3d microBlock;
902     GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, 0, &microBlock);
903 
904     INT_32 overlap = GetEffectiveNumPipes() - static_cast<INT_32>(microBlock.w);
905 
906     overlap++;
907 
908     if ((overlap < 0) || (IsStandardSwizzle(resourceType, swizzleMode) == TRUE))
909     {
910         overlap = 0;
911     }
912     return overlap;
913 }
914 
915 /**
916 ************************************************************************************************************************
917 *   Gfx11Lib::GetPipeRotateAmount
918 *
919 *   @brief
920 *       Get pipe rotate amount
921 *
922 *   @return
923 *       Pipe rotate amount
924 ************************************************************************************************************************
925 */
926 
GetPipeRotateAmount(AddrResourceType resourceType,AddrSwizzleMode swizzleMode) const927 INT_32 Gfx11Lib::GetPipeRotateAmount(
928     AddrResourceType resourceType,      ///< [in] Resource type
929     AddrSwizzleMode  swizzleMode        ///< [in] Swizzle mode
930     ) const
931 {
932     INT_32 amount = 0;
933 
934     if ((m_pipesLog2 >= (m_numSaLog2 + 1)) && (m_pipesLog2 > 1))
935     {
936         amount = ((m_pipesLog2 == (m_numSaLog2 + 1)) && IsRbAligned(resourceType, swizzleMode)) ?
937                  1 : m_pipesLog2 - (m_numSaLog2 + 1);
938     }
939 
940     return amount;
941 }
942 
943 /**
944 ************************************************************************************************************************
945 *   Gfx11Lib::GetMetaBlkSize
946 *
947 *   @brief
948 *       Get metadata block size
949 *
950 *   @return
951 *       Meta block size
952 ************************************************************************************************************************
953 */
GetMetaBlkSize(Gfx11DataType dataType,AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 elemLog2,UINT_32 numSamplesLog2,BOOL_32 pipeAlign,Dim3d * pBlock) const954 UINT_32 Gfx11Lib::GetMetaBlkSize(
955     Gfx11DataType    dataType,          ///< [in] Data type
956     AddrResourceType resourceType,      ///< [in] Resource type
957     AddrSwizzleMode  swizzleMode,       ///< [in] Swizzle mode
958     UINT_32          elemLog2,          ///< [in] element size log2
959     UINT_32          numSamplesLog2,    ///< [in] number of samples
960     BOOL_32          pipeAlign,         ///< [in] pipe align
961     Dim3d*           pBlock             ///< [out] block size
962     ) const
963 {
964     INT_32 metablkSizeLog2;
965 
966     const INT_32 metaElemSizeLog2   = GetMetaElementSizeLog2(dataType);
967     const INT_32 metaCacheSizeLog2  = GetMetaCacheSizeLog2(dataType);
968     const INT_32 compBlkSizeLog2    = (dataType == Gfx11DataColor) ? 8 : 6 + numSamplesLog2 + elemLog2;
969     const INT_32 metaBlkSamplesLog2 = numSamplesLog2;
970     const INT_32 dataBlkSizeLog2    = GetBlockSizeLog2(swizzleMode);
971     INT_32       numPipesLog2       = m_pipesLog2;
972 
973     if (IsThin(resourceType, swizzleMode))
974     {
975         if ((pipeAlign == FALSE) ||
976             (IsStandardSwizzle(resourceType, swizzleMode) == TRUE) ||
977             (IsDisplaySwizzle(resourceType, swizzleMode)  == TRUE))
978         {
979             if (pipeAlign)
980             {
981                 metablkSizeLog2 = Max(static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2, 12);
982                 metablkSizeLog2 = Min(metablkSizeLog2, dataBlkSizeLog2);
983             }
984             else
985             {
986                 metablkSizeLog2 = Min(dataBlkSizeLog2, 12);
987             }
988         }
989         else
990         {
991             if ((m_pipesLog2 == m_numSaLog2 + 1) && (m_pipesLog2 > 1))
992             {
993                 numPipesLog2++;
994             }
995 
996             INT_32 pipeRotateLog2 = GetPipeRotateAmount(resourceType, swizzleMode);
997 
998             if (numPipesLog2 >= 4)
999             {
1000                 INT_32 overlapLog2 = GetMetaOverlapLog2(dataType, resourceType, swizzleMode, elemLog2, numSamplesLog2);
1001 
1002                 // In 16Bpe 8xaa, we have an extra overlap bit
1003                 if ((pipeRotateLog2 > 0)  &&
1004                     (elemLog2 == 4)       &&
1005                     (numSamplesLog2 == 3) &&
1006                     (IsZOrderSwizzle(swizzleMode) || (GetEffectiveNumPipes() > 3)))
1007                 {
1008                     overlapLog2++;
1009                 }
1010 
1011                 metablkSizeLog2 = metaCacheSizeLog2 + overlapLog2 + numPipesLog2;
1012                 metablkSizeLog2 = Max(metablkSizeLog2, static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2);
1013             }
1014             else
1015             {
1016                 metablkSizeLog2 = Max(static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2, 12);
1017             }
1018 
1019             if (dataType == Gfx11DataDepthStencil)
1020             {
1021                 // For htile surfaces, pad meta block size to 2K * num_pipes
1022                 metablkSizeLog2 = Max(metablkSizeLog2, 11 + numPipesLog2);
1023             }
1024 
1025             const INT_32 compFragLog2 = numSamplesLog2;
1026 
1027             if  (IsRtOptSwizzle(swizzleMode) && (compFragLog2 > 1) && (pipeRotateLog2 >= 1))
1028             {
1029                 const INT_32 tmp = 8 + m_pipesLog2 + Max(pipeRotateLog2, compFragLog2 - 1);
1030 
1031                 metablkSizeLog2 = Max(metablkSizeLog2, tmp);
1032             }
1033         }
1034 
1035         const INT_32 metablkBitsLog2 =
1036             metablkSizeLog2 + compBlkSizeLog2 - elemLog2 - metaBlkSamplesLog2 - metaElemSizeLog2;
1037         pBlock->w = 1 << ((metablkBitsLog2 >> 1) + (metablkBitsLog2 & 1));
1038         pBlock->h = 1 << (metablkBitsLog2 >> 1);
1039         pBlock->d = 1;
1040     }
1041     else
1042     {
1043         ADDR_ASSERT(IsThick(resourceType, swizzleMode));
1044 
1045         if (pipeAlign)
1046         {
1047             if ((m_pipesLog2 == m_numSaLog2 + 1) &&
1048                 (m_pipesLog2 > 1)                &&
1049                 IsRbAligned(resourceType, swizzleMode))
1050             {
1051                 numPipesLog2++;
1052             }
1053 
1054             const INT_32 overlapLog2 = Get3DMetaOverlapLog2(resourceType, swizzleMode, elemLog2);
1055 
1056             metablkSizeLog2 = metaCacheSizeLog2 + overlapLog2 + numPipesLog2;
1057             metablkSizeLog2 = Max(metablkSizeLog2, static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2);
1058             metablkSizeLog2 = Max(metablkSizeLog2, 12);
1059         }
1060         else
1061         {
1062             metablkSizeLog2 = 12;
1063         }
1064 
1065         const INT_32 metablkBitsLog2 =
1066             metablkSizeLog2 + compBlkSizeLog2 - elemLog2 - metaBlkSamplesLog2 - metaElemSizeLog2;
1067         pBlock->w = 1 << ((metablkBitsLog2 / 3) + (((metablkBitsLog2 % 3) > 0) ? 1 : 0));
1068         pBlock->h = 1 << ((metablkBitsLog2 / 3) + (((metablkBitsLog2 % 3) > 1) ? 1 : 0));
1069         pBlock->d = 1 << (metablkBitsLog2 / 3);
1070     }
1071 
1072     return (1 << static_cast<UINT_32>(metablkSizeLog2));
1073 }
1074 
1075 /**
1076 ************************************************************************************************************************
1077 *   Gfx11Lib::ConvertSwizzlePatternToEquation
1078 *
1079 *   @brief
1080 *       Convert swizzle pattern to equation.
1081 *
1082 *   @return
1083 *       N/A
1084 ************************************************************************************************************************
1085 */
ConvertSwizzlePatternToEquation(UINT_32 elemLog2,AddrResourceType rsrcType,AddrSwizzleMode swMode,const ADDR_SW_PATINFO * pPatInfo,ADDR_EQUATION * pEquation) const1086 VOID Gfx11Lib::ConvertSwizzlePatternToEquation(
1087     UINT_32                elemLog2,  ///< [in] element bytes log2
1088     AddrResourceType       rsrcType,  ///< [in] resource type
1089     AddrSwizzleMode        swMode,    ///< [in] swizzle mode
1090     const ADDR_SW_PATINFO* pPatInfo,  ///< [in] swizzle pattern infor
1091     ADDR_EQUATION*         pEquation) ///< [out] equation converted from swizzle pattern
1092     const
1093 {
1094     ADDR_BIT_SETTING fullSwizzlePattern[ADDR_MAX_EQUATION_BIT];
1095     GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);
1096 
1097     const ADDR_BIT_SETTING* pSwizzle      = fullSwizzlePattern;
1098     const UINT_32           blockSizeLog2 = GetBlockSizeLog2(swMode);
1099     memset(pEquation, 0, sizeof(ADDR_EQUATION));
1100     pEquation->numBits            = blockSizeLog2;
1101     pEquation->numBitComponents   = pPatInfo->maxItemCount;
1102     pEquation->stackedDepthSlices = FALSE;
1103 
1104     for (UINT_32 i = 0; i < elemLog2; i++)
1105     {
1106         pEquation->addr[i].channel = 0;
1107         pEquation->addr[i].valid   = 1;
1108         pEquation->addr[i].index   = i;
1109     }
1110 
1111     if (IsXor(swMode) == FALSE)
1112     {
1113         // Use simplified logic when we only have one bit-component
1114         for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)
1115         {
1116             ADDR_ASSERT(IsPow2(pSwizzle[i].value));
1117 
1118             if (pSwizzle[i].x != 0)
1119             {
1120                 ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].x)));
1121 
1122                 pEquation->addr[i].channel = 0;
1123                 pEquation->addr[i].valid   = 1;
1124                 pEquation->addr[i].index   = Log2(pSwizzle[i].x) + elemLog2;
1125             }
1126             else if (pSwizzle[i].y != 0)
1127             {
1128                 ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].y)));
1129 
1130                 pEquation->addr[i].channel = 1;
1131                 pEquation->addr[i].valid   = 1;
1132                 pEquation->addr[i].index   = Log2(pSwizzle[i].y);
1133             }
1134             else
1135             {
1136                 ADDR_ASSERT(pSwizzle[i].z != 0);
1137                 ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].z)));
1138 
1139                 pEquation->addr[i].channel = 2;
1140                 pEquation->addr[i].valid   = 1;
1141                 pEquation->addr[i].index   = Log2(pSwizzle[i].z);
1142             }
1143         }
1144     }
1145     else
1146     {
1147         Dim3d dim;
1148         ComputeBlockDimension(&dim.w, &dim.h, &dim.d, 8u << elemLog2, rsrcType, swMode);
1149 
1150         const UINT_32 blkXLog2 = Log2(dim.w);
1151         const UINT_32 blkYLog2 = Log2(dim.h);
1152         const UINT_32 blkZLog2 = Log2(dim.d);
1153         const UINT_32 blkXMask = dim.w - 1;
1154         const UINT_32 blkYMask = dim.h - 1;
1155         const UINT_32 blkZMask = dim.d - 1;
1156 
1157         ADDR_BIT_SETTING swizzle[ADDR_MAX_EQUATION_BIT] = {};
1158         memcpy(&swizzle, pSwizzle, sizeof(swizzle));
1159         UINT_32          xMask = 0;
1160         UINT_32          yMask = 0;
1161         UINT_32          zMask = 0;
1162 
1163         for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)
1164         {
1165             for (UINT_32 bitComp = 0; bitComp < ADDR_MAX_EQUATION_COMP; bitComp++)
1166             {
1167                 if (swizzle[i].value == 0)
1168                 {
1169                     ADDR_ASSERT(bitComp != 0); // Bits above element size must have at least one addr-bit
1170                     ADDR_ASSERT(bitComp <= pPatInfo->maxItemCount);
1171                     break;
1172                 }
1173 
1174                 if (swizzle[i].x != 0)
1175                 {
1176                     const UINT_32 xLog2 = BitScanForward(swizzle[i].x);
1177                     swizzle[i].x = UnsetLeastBit(swizzle[i].x);
1178                     xMask |= (1 << xLog2);
1179 
1180                     pEquation->comps[bitComp][i].channel = 0;
1181                     pEquation->comps[bitComp][i].valid   = 1;
1182                     pEquation->comps[bitComp][i].index   = xLog2 + elemLog2;
1183                 }
1184                 else if (swizzle[i].y != 0)
1185                 {
1186                     const UINT_32 yLog2 = BitScanForward(swizzle[i].y);
1187                     swizzle[i].y = UnsetLeastBit(swizzle[i].y);
1188                     yMask |= (1 << yLog2);
1189 
1190                     pEquation->comps[bitComp][i].channel = 1;
1191                     pEquation->comps[bitComp][i].valid   = 1;
1192                     pEquation->comps[bitComp][i].index   = yLog2;
1193                 }
1194                 else if (swizzle[i].z != 0)
1195                 {
1196                     const UINT_32 zLog2 = BitScanForward(swizzle[i].z);
1197                     swizzle[i].z = UnsetLeastBit(swizzle[i].z);
1198                     zMask |= (1 << zLog2);
1199 
1200                     pEquation->comps[bitComp][i].channel = 2;
1201                     pEquation->comps[bitComp][i].valid   = 1;
1202                     pEquation->comps[bitComp][i].index   = zLog2;
1203                 }
1204                 else
1205                 {
1206                     // This function doesn't handle MSAA (must update block dims, here, and consumers)
1207                     ADDR_ASSERT_ALWAYS();
1208                 }
1209             }
1210             ADDR_ASSERT(swizzle[i].value == 0); // We missed an xor? Are there too many?
1211         }
1212 
1213         // We missed an address bit for coords inside the block?
1214         // That means two coords will land on the same addr, which is bad.
1215         ADDR_ASSERT(((xMask & blkXMask) == blkXMask) &&
1216                     ((yMask & blkYMask) == blkYMask) &&
1217                     ((zMask & blkZMask) == blkZMask));
1218         // We're sourcing from outside our block? That won't fly for PRTs, which need to be movable.
1219         // Non-xor modes can also be used for 2D PRTs but they're handled in the simplified logic above.
1220         ADDR_ASSERT((IsPrt(swMode) == false) ||
1221                     ((xMask == blkXMask) &&
1222                      (yMask == blkYMask) &&
1223                      (zMask == blkZMask)));
1224     }
1225 }
1226 
1227 /**
1228 ************************************************************************************************************************
1229 *   Gfx11Lib::InitEquationTable
1230 *
1231 *   @brief
1232 *       Initialize Equation table.
1233 *
1234 *   @return
1235 *       N/A
1236 ************************************************************************************************************************
1237 */
InitEquationTable()1238 VOID Gfx11Lib::InitEquationTable()
1239 {
1240     memset(m_equationTable, 0, sizeof(m_equationTable));
1241 
1242     for (UINT_32 rsrcTypeIdx = 0; rsrcTypeIdx < MaxRsrcType; rsrcTypeIdx++)
1243     {
1244         const AddrResourceType rsrcType = static_cast<AddrResourceType>(rsrcTypeIdx + ADDR_RSRC_TEX_2D);
1245 
1246         for (UINT_32 swModeIdx = 0; swModeIdx < MaxSwModeType; swModeIdx++)
1247         {
1248             const AddrSwizzleMode swMode = static_cast<AddrSwizzleMode>(swModeIdx);
1249 
1250             for (UINT_32 elemLog2 = 0; elemLog2 < MaxElementBytesLog2; elemLog2++)
1251             {
1252                 UINT_32                equationIndex = ADDR_INVALID_EQUATION_INDEX;
1253                 const ADDR_SW_PATINFO* pPatInfo      = GetSwizzlePatternInfo(swMode, rsrcType, elemLog2, 1);
1254 
1255                 if (pPatInfo != NULL)
1256                 {
1257                     ADDR_ASSERT(IsValidSwMode(swMode));
1258                     ADDR_EQUATION equation = {};
1259 
1260                     ConvertSwizzlePatternToEquation(elemLog2, rsrcType, swMode, pPatInfo, &equation);
1261 
1262                     equationIndex = m_numEquations;
1263                     ADDR_ASSERT(equationIndex < EquationTableSize);
1264 
1265                     m_equationTable[equationIndex] = equation;
1266 
1267                     m_numEquations++;
1268                 }
1269 
1270                 m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2] = equationIndex;
1271             }
1272         }
1273     }
1274 }
1275 
1276 /**
1277 ************************************************************************************************************************
1278 *   Gfx11Lib::HwlGetEquationIndex
1279 *
1280 *   @brief
1281 *       Interface function stub of GetEquationIndex
1282 *
1283 *   @return
1284 *       ADDR_E_RETURNCODE
1285 ************************************************************************************************************************
1286 */
HwlGetEquationIndex(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const1287 UINT_32 Gfx11Lib::HwlGetEquationIndex(
1288     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
1289     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
1290     ) const
1291 {
1292     UINT_32 equationIdx = ADDR_INVALID_EQUATION_INDEX;
1293 
1294     if ((pIn->resourceType == ADDR_RSRC_TEX_2D) ||
1295         (pIn->resourceType == ADDR_RSRC_TEX_3D))
1296     {
1297         const UINT_32 rsrcTypeIdx = static_cast<UINT_32>(pIn->resourceType) - 1;
1298         const UINT_32 swModeIdx   = static_cast<UINT_32>(pIn->swizzleMode);
1299         const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);
1300 
1301         equationIdx = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2];
1302     }
1303 
1304     if (pOut->pMipInfo != NULL)
1305     {
1306         for (UINT_32 i = 0; i < pIn->numMipLevels; i++)
1307         {
1308             pOut->pMipInfo[i].equationIndex = equationIdx;
1309         }
1310     }
1311 
1312     return equationIdx;
1313 }
1314 
1315 /**
1316 ************************************************************************************************************************
1317 *   Gfx11Lib::GetValidDisplaySwizzleModes
1318 *
1319 *   @brief
1320 *       Get valid swizzle modes mask for displayable surface
1321 *
1322 *   @return
1323 *       Valid swizzle modes mask for displayable surface
1324 ************************************************************************************************************************
1325 */
GetValidDisplaySwizzleModes(UINT_32 bpp) const1326 UINT_32 Gfx11Lib::GetValidDisplaySwizzleModes(
1327     UINT_32 bpp
1328     ) const
1329 {
1330     UINT_32 swModeMask = 0;
1331 
1332     if (bpp <= 64)
1333     {
1334         const ChipFamily  family = GetChipFamily();
1335 
1336         swModeMask = Dcn32SwModeMask;
1337 
1338         if (false
1339             || (m_settings.isGfx1103)
1340             || (m_settings.isGfx1150)
1341            )
1342         {
1343             // Not all GPUs support displaying with 256kB swizzle modes.
1344             swModeMask &= ~((1u << ADDR_SW_256KB_D_X) |
1345                             (1u << ADDR_SW_256KB_R_X));
1346         }
1347     }
1348 
1349     return swModeMask;
1350 }
1351 
1352 /**
1353 ************************************************************************************************************************
1354 *   Gfx11Lib::IsValidDisplaySwizzleMode
1355 *
1356 *   @brief
1357 *       Check if a swizzle mode is supported by display engine
1358 *
1359 *   @return
1360 *       TRUE is swizzle mode is supported by display engine
1361 ************************************************************************************************************************
1362 */
IsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn) const1363 BOOL_32 Gfx11Lib::IsValidDisplaySwizzleMode(
1364     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn     ///< [in] input structure
1365     ) const
1366 {
1367     ADDR_ASSERT(pIn->resourceType == ADDR_RSRC_TEX_2D);
1368 
1369     return (GetValidDisplaySwizzleModes(pIn->bpp) & (1 << pIn->swizzleMode)) ? TRUE : FALSE;
1370 }
1371 
1372 /**
1373 ************************************************************************************************************************
1374 *   Gfx11Lib::GetMaxNumMipsInTail
1375 *
1376 *   @brief
1377 *       Return max number of mips in tails
1378 *
1379 *   @return
1380 *       Max number of mips in tails
1381 ************************************************************************************************************************
1382 */
GetMaxNumMipsInTail(UINT_32 blockSizeLog2,BOOL_32 isThin) const1383 UINT_32 Gfx11Lib::GetMaxNumMipsInTail(
1384     UINT_32 blockSizeLog2,     ///< block size log2
1385     BOOL_32 isThin             ///< is thin or thick
1386     ) const
1387 {
1388     UINT_32 effectiveLog2 = blockSizeLog2;
1389 
1390     if (isThin == FALSE)
1391     {
1392         effectiveLog2 -= (blockSizeLog2 - 8) / 3;
1393     }
1394 
1395     return (effectiveLog2 <= 11) ? (1 + (1 << (effectiveLog2 - 9))) : (effectiveLog2 - 4);
1396 }
1397 
1398 /**
1399 ************************************************************************************************************************
1400 *   Gfx11Lib::HwlComputePipeBankXor
1401 *
1402 *   @brief
1403 *       Generate a PipeBankXor value to be ORed into bits above pipeInterleaveBits of address
1404 *
1405 *   @return
1406 *       PipeBankXor value
1407 ************************************************************************************************************************
1408 */
HwlComputePipeBankXor(const ADDR2_COMPUTE_PIPEBANKXOR_INPUT * pIn,ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT * pOut) const1409 ADDR_E_RETURNCODE Gfx11Lib::HwlComputePipeBankXor(
1410     const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,     ///< [in] input structure
1411     ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT*      pOut     ///< [out] output structure
1412     ) const
1413 {
1414     if (IsNonPrtXor(pIn->swizzleMode))
1415     {
1416         pOut->pipeBankXor = 0;
1417     }
1418     else
1419     {
1420         pOut->pipeBankXor = 0;
1421     }
1422 
1423     return ADDR_OK;
1424 }
1425 
1426 /**
1427 ************************************************************************************************************************
1428 *   Gfx11Lib::HwlComputeSlicePipeBankXor
1429 *
1430 *   @brief
1431 *       Generate slice PipeBankXor value based on base PipeBankXor value and slice id
1432 *
1433 *   @return
1434 *       PipeBankXor value
1435 ************************************************************************************************************************
1436 */
HwlComputeSlicePipeBankXor(const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT * pIn,ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT * pOut) const1437 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSlicePipeBankXor(
1438     const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,   ///< [in] input structure
1439     ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT*      pOut   ///< [out] output structure
1440     ) const
1441 {
1442     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1443 
1444     if (IsNonPrtXor(pIn->swizzleMode))
1445     {
1446         if (pIn->bpe == 0)
1447         {
1448             ADDR_ASSERT_ALWAYS();
1449 
1450             // Require a valid bytes-per-element value passed from client...
1451             returnCode = ADDR_INVALIDPARAMS;
1452         }
1453         else
1454         {
1455             const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(pIn->swizzleMode,
1456                                                                     pIn->resourceType,
1457                                                                     Log2(pIn->bpe >> 3),
1458                                                                     1);
1459 
1460             if (pPatInfo != NULL)
1461             {
1462                 ADDR_BIT_SETTING fullSwizzlePattern[20];
1463                 GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);
1464 
1465                 const UINT_32 pipeBankXorOffset =
1466                     ComputeOffsetFromSwizzlePattern(reinterpret_cast<const UINT_64*>(fullSwizzlePattern),
1467                                                     GetBlockSizeLog2(pIn->swizzleMode),
1468                                                     0,
1469                                                     0,
1470                                                     pIn->slice,
1471                                                     0);
1472 
1473                 const UINT_32 pipeBankXor = pipeBankXorOffset >> m_pipeInterleaveLog2;
1474 
1475                 // Should have no bit set under pipe interleave
1476                 ADDR_ASSERT((pipeBankXor << m_pipeInterleaveLog2) == pipeBankXorOffset);
1477 
1478                 pOut->pipeBankXor = pIn->basePipeBankXor ^ pipeBankXor;
1479             }
1480             else
1481             {
1482                 // Should never come here...
1483                 ADDR_NOT_IMPLEMENTED();
1484 
1485                 returnCode = ADDR_NOTSUPPORTED;
1486             }
1487         }
1488     }
1489     else
1490     {
1491         pOut->pipeBankXor = 0;
1492     }
1493 
1494     return returnCode;
1495 }
1496 
1497 /**
1498 ************************************************************************************************************************
1499 *   Gfx11Lib::HwlComputeSubResourceOffsetForSwizzlePattern
1500 *
1501 *   @brief
1502 *       Compute sub resource offset to support swizzle pattern
1503 *
1504 *   @return
1505 *       Offset
1506 ************************************************************************************************************************
1507 */
HwlComputeSubResourceOffsetForSwizzlePattern(const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT * pIn,ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT * pOut) const1508 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSubResourceOffsetForSwizzlePattern(
1509     const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,    ///< [in] input structure
1510     ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT*      pOut    ///< [out] output structure
1511     ) const
1512 {
1513     ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));
1514 
1515     pOut->offset = pIn->slice * pIn->sliceSize + pIn->macroBlockOffset;
1516 
1517     return ADDR_OK;
1518 }
1519 
1520 /**
1521 ************************************************************************************************************************
1522 *   Gfx11Lib::HwlComputeNonBlockCompressedView
1523 *
1524 *   @brief
1525 *       Compute non-block-compressed view for a given mipmap level/slice.
1526 *
1527 *   @return
1528 *       ADDR_E_RETURNCODE
1529 ************************************************************************************************************************
1530 */
HwlComputeNonBlockCompressedView(const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT * pIn,ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT * pOut) const1531 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeNonBlockCompressedView(
1532     const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,    ///< [in] input structure
1533     ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT*      pOut    ///< [out] output structure
1534     ) const
1535 {
1536     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1537 
1538     if (IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE)
1539     {
1540         // Only thin swizzle mode can have a NonBC view...
1541         returnCode = ADDR_INVALIDPARAMS;
1542     }
1543     else if (((pIn->format < ADDR_FMT_ASTC_4x4) || (pIn->format > ADDR_FMT_ETC2_128BPP)) &&
1544              ((pIn->format < ADDR_FMT_BC1) || (pIn->format > ADDR_FMT_BC7)))
1545     {
1546         // Only support BC1~BC7, ASTC, or ETC2 for now...
1547         returnCode = ADDR_NOTSUPPORTED;
1548     }
1549     else
1550     {
1551         UINT_32 bcWidth, bcHeight;
1552         UINT_32 bpp = GetElemLib()->GetBitsPerPixel(pIn->format, NULL, &bcWidth, &bcHeight);
1553 
1554         ADDR2_COMPUTE_SURFACE_INFO_INPUT infoIn = {};
1555         infoIn.flags        = pIn->flags;
1556         infoIn.swizzleMode  = pIn->swizzleMode;
1557         infoIn.resourceType = pIn->resourceType;
1558         infoIn.bpp          = bpp;
1559         infoIn.width        = RoundUpQuotient(pIn->width, bcWidth);
1560         infoIn.height       = RoundUpQuotient(pIn->height, bcHeight);
1561         infoIn.numSlices    = pIn->numSlices;
1562         infoIn.numMipLevels = pIn->numMipLevels;
1563         infoIn.numSamples   = 1;
1564         infoIn.numFrags     = 1;
1565 
1566         ADDR2_MIP_INFO mipInfo[MaxMipLevels] = {};
1567 
1568         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT infoOut = {};
1569         infoOut.pMipInfo = mipInfo;
1570 
1571         const BOOL_32 tiled = (pIn->swizzleMode != ADDR_SW_LINEAR) ? TRUE : FALSE;
1572 
1573         if (tiled)
1574         {
1575             returnCode = HwlComputeSurfaceInfoTiled(&infoIn, &infoOut);
1576         }
1577         else
1578         {
1579             returnCode = HwlComputeSurfaceInfoLinear(&infoIn, &infoOut);
1580         }
1581 
1582         if (returnCode == ADDR_OK)
1583         {
1584             ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT subOffIn = {};
1585             subOffIn.swizzleMode      = infoIn.swizzleMode;
1586             subOffIn.resourceType     = infoIn.resourceType;
1587             subOffIn.slice            = pIn->slice;
1588             subOffIn.sliceSize        = infoOut.sliceSize;
1589             subOffIn.macroBlockOffset = mipInfo[pIn->mipId].macroBlockOffset;
1590             subOffIn.mipTailOffset    = mipInfo[pIn->mipId].mipTailOffset;
1591 
1592             ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT subOffOut = {};
1593 
1594             // For any mipmap level, move nonBc view base address by offset
1595             HwlComputeSubResourceOffsetForSwizzlePattern(&subOffIn, &subOffOut);
1596             pOut->offset = subOffOut.offset;
1597 
1598             ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT slicePbXorIn = {};
1599             slicePbXorIn.bpe             = infoIn.bpp;
1600             slicePbXorIn.swizzleMode     = infoIn.swizzleMode;
1601             slicePbXorIn.resourceType    = infoIn.resourceType;
1602             slicePbXorIn.basePipeBankXor = pIn->pipeBankXor;
1603             slicePbXorIn.slice           = pIn->slice;
1604 
1605             ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT slicePbXorOut = {};
1606 
1607             // For any mipmap level, nonBc view should use computed pbXor
1608             HwlComputeSlicePipeBankXor(&slicePbXorIn, &slicePbXorOut);
1609             pOut->pipeBankXor = slicePbXorOut.pipeBankXor;
1610 
1611             const BOOL_32 inTail           = tiled && (pIn->mipId >= infoOut.firstMipIdInTail) ? TRUE : FALSE;
1612             const UINT_32 requestMipWidth  = RoundUpQuotient(Max(pIn->width >> pIn->mipId, 1u), bcWidth);
1613             const UINT_32 requestMipHeight = RoundUpQuotient(Max(pIn->height >> pIn->mipId, 1u), bcHeight);
1614 
1615             if (inTail)
1616             {
1617                 // For mipmap level that is in mip tail block, hack a lot of things...
1618                 // Basically all mipmap levels in tail block will be viewed as a small mipmap chain that all levels
1619                 // are fit in tail block:
1620 
1621                 // - mipId = relative mip id (which is counted from first mip ID in tail in original mip chain)
1622                 pOut->mipId = pIn->mipId - infoOut.firstMipIdInTail;
1623 
1624                 // - at least 2 mipmap levels (since only 1 mipmap level will not be viewed as mipmap!)
1625                 pOut->numMipLevels = Max(infoIn.numMipLevels - infoOut.firstMipIdInTail, 2u);
1626 
1627                 // - (mip0) width = requestMipWidth << mipId, the value can't exceed mip tail dimension threshold
1628                 pOut->unalignedWidth = Min(requestMipWidth << pOut->mipId, infoOut.blockWidth / 2);
1629 
1630                 // - (mip0) height = requestMipHeight << mipId, the value can't exceed mip tail dimension threshold
1631                 pOut->unalignedHeight = Min(requestMipHeight << pOut->mipId, infoOut.blockHeight);
1632             }
1633             // This check should cover at least mipId == 0
1634             else if (requestMipWidth << pIn->mipId == infoIn.width)
1635             {
1636                 // For mipmap level [N] that is not in mip tail block and downgraded without losing element:
1637                 // - only one mipmap level and mipId = 0
1638                 pOut->mipId        = 0;
1639                 pOut->numMipLevels = 1;
1640 
1641                 // (mip0) width = requestMipWidth
1642                 pOut->unalignedWidth = requestMipWidth;
1643 
1644                 // (mip0) height = requestMipHeight
1645                 pOut->unalignedHeight = requestMipHeight;
1646             }
1647             else
1648             {
1649                 // For mipmap level [N] that is not in mip tail block and downgraded with element losing,
1650                 // We have to make it a multiple mipmap view (2 levels view here), add one extra element if needed,
1651                 // because single mip view may have different pitch value than original (multiple) mip view...
1652                 // A simple case would be:
1653                 // - 64KB block swizzle mode, 8 Bytes-Per-Element. Block dim = [0x80, 0x40]
1654                 // - 2 mipmap levels with API mip0 width = 0x401/mip1 width = 0x200 and non-BC view
1655                 //   mip0 width = 0x101/mip1 width = 0x80
1656                 // By multiple mip view, the pitch for mip level 1 would be 0x100 bytes, due to rounding up logic in
1657                 // GetMipSize(), and by single mip level view the pitch will only be 0x80 bytes.
1658 
1659                 // - 2 levels and mipId = 1
1660                 pOut->mipId        = 1;
1661                 pOut->numMipLevels = 2;
1662 
1663                 const UINT_32 upperMipWidth  = RoundUpQuotient(Max(pIn->width >> (pIn->mipId - 1), 1u), bcWidth);
1664                 const UINT_32 upperMipHeight = RoundUpQuotient(Max(pIn->height >> (pIn->mipId - 1), 1u), bcHeight);
1665 
1666                 const BOOL_32 needToAvoidInTail =
1667                     tiled && (requestMipWidth <= infoOut.blockWidth / 2) && (requestMipHeight <= infoOut.blockHeight) ?
1668                     TRUE : FALSE;
1669 
1670                 const UINT_32 hwMipWidth  = PowTwoAlign(ShiftCeil(infoIn.width, pIn->mipId), infoOut.blockWidth);
1671                 const UINT_32 hwMipHeight = PowTwoAlign(ShiftCeil(infoIn.height, pIn->mipId), infoOut.blockHeight);
1672 
1673                 const BOOL_32 needExtraWidth =
1674                     ((upperMipWidth < requestMipWidth * 2) ||
1675                      ((upperMipWidth == requestMipWidth * 2) &&
1676                       ((needToAvoidInTail == TRUE) ||
1677                        (hwMipWidth > PowTwoAlign(requestMipWidth, infoOut.blockWidth))))) ? TRUE : FALSE;
1678 
1679                 const BOOL_32 needExtraHeight =
1680                     ((upperMipHeight < requestMipHeight * 2) ||
1681                      ((upperMipHeight == requestMipHeight * 2) &&
1682                       ((needToAvoidInTail == TRUE) ||
1683                        (hwMipHeight > PowTwoAlign(requestMipHeight, infoOut.blockHeight))))) ? TRUE : FALSE;
1684 
1685                 // (mip0) width = requestLastMipLevelWidth
1686                 pOut->unalignedWidth  = upperMipWidth + (needExtraWidth ? 1: 0);
1687 
1688                 // (mip0) height = requestLastMipLevelHeight
1689                 pOut->unalignedHeight = upperMipHeight + (needExtraHeight ? 1: 0);
1690             }
1691 
1692             // Assert the downgrading from this mip[0] width would still generate correct mip[N] width
1693             ADDR_ASSERT(ShiftRight(pOut->unalignedWidth, pOut->mipId) == requestMipWidth);
1694             // Assert the downgrading from this mip[0] height would still generate correct mip[N] height
1695             ADDR_ASSERT(ShiftRight(pOut->unalignedHeight, pOut->mipId) == requestMipHeight);
1696         }
1697     }
1698 
1699     return returnCode;
1700 }
1701 
1702 /**
1703 ************************************************************************************************************************
1704 *   Gfx11Lib::ValidateNonSwModeParams
1705 *
1706 *   @brief
1707 *       Validate compute surface info params except swizzle mode
1708 *
1709 *   @return
1710 *       TRUE if parameters are valid, FALSE otherwise
1711 ************************************************************************************************************************
1712 */
ValidateNonSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn) const1713 BOOL_32 Gfx11Lib::ValidateNonSwModeParams(
1714     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
1715 {
1716     BOOL_32 valid = TRUE;
1717 
1718     if ((pIn->bpp == 0) || (pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8))
1719     {
1720         ADDR_ASSERT_ALWAYS();
1721         valid = FALSE;
1722     }
1723     else if (pIn->flags.fmask == 1)
1724     {
1725         // There is no FMASK for GFX11 ASICs
1726         ADDR_ASSERT_ALWAYS();
1727         valid = FALSE;
1728     }
1729     else if (pIn->numSamples > 8)
1730     {
1731         // There is no EQAA support for GFX11 ASICs, so the max number of sample is 8
1732         ADDR_ASSERT_ALWAYS();
1733         valid = FALSE;
1734     }
1735     else if ((pIn->numFrags != 0) && (pIn->numSamples != pIn->numFrags))
1736     {
1737         // There is no EQAA support for GFX11 ASICs, so the number of sample has to be same as number of fragment
1738         ADDR_ASSERT_ALWAYS();
1739         valid = FALSE;
1740     }
1741 
1742     const ADDR2_SURFACE_FLAGS flags    = pIn->flags;
1743     const AddrResourceType    rsrcType = pIn->resourceType;
1744     const BOOL_32             mipmap   = (pIn->numMipLevels > 1);
1745     const BOOL_32             msaa     = (pIn->numSamples > 1);
1746     const BOOL_32             display  = flags.display;
1747     const BOOL_32             tex3d    = IsTex3d(rsrcType);
1748     const BOOL_32             tex2d    = IsTex2d(rsrcType);
1749     const BOOL_32             tex1d    = IsTex1d(rsrcType);
1750     const BOOL_32             stereo   = flags.qbStereo;
1751 
1752     // Resource type check
1753     if (tex1d)
1754     {
1755         if (msaa || display || stereo)
1756         {
1757             ADDR_ASSERT_ALWAYS();
1758             valid = FALSE;
1759         }
1760     }
1761     else if (tex2d)
1762     {
1763         if ((msaa && mipmap) || (stereo && msaa) || (stereo && mipmap))
1764         {
1765             ADDR_ASSERT_ALWAYS();
1766             valid = FALSE;
1767         }
1768     }
1769     else if (tex3d)
1770     {
1771         if (msaa || display || stereo)
1772         {
1773             ADDR_ASSERT_ALWAYS();
1774             valid = FALSE;
1775         }
1776     }
1777     else
1778     {
1779         ADDR_ASSERT_ALWAYS();
1780         valid = FALSE;
1781     }
1782 
1783     return valid;
1784 }
1785 
1786 /**
1787 ************************************************************************************************************************
1788 *   Gfx11Lib::ValidateSwModeParams
1789 *
1790 *   @brief
1791 *       Validate compute surface info related to swizzle mode
1792 *
1793 *   @return
1794 *       TRUE if parameters are valid, FALSE otherwise
1795 ************************************************************************************************************************
1796 */
ValidateSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn) const1797 BOOL_32 Gfx11Lib::ValidateSwModeParams(
1798     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
1799 {
1800     BOOL_32 valid = TRUE;
1801 
1802     if (pIn->swizzleMode >= ADDR_SW_MAX_TYPE)
1803     {
1804         ADDR_ASSERT_ALWAYS();
1805         valid = FALSE;
1806     }
1807     else if (IsValidSwMode(pIn->swizzleMode) == FALSE)
1808     {
1809         ADDR_ASSERT_ALWAYS();
1810         valid = FALSE;
1811     }
1812 
1813     const ADDR2_SURFACE_FLAGS flags       = pIn->flags;
1814     const AddrResourceType    rsrcType    = pIn->resourceType;
1815     const AddrSwizzleMode     swizzle     = pIn->swizzleMode;
1816     const BOOL_32             msaa        = (pIn->numSamples > 1);
1817     const BOOL_32             zbuffer     = flags.depth || flags.stencil;
1818     const BOOL_32             color       = flags.color;
1819     const BOOL_32             display     = flags.display;
1820     const BOOL_32             tex3d       = IsTex3d(rsrcType);
1821     const BOOL_32             tex2d       = IsTex2d(rsrcType);
1822     const BOOL_32             tex1d       = IsTex1d(rsrcType);
1823     const BOOL_32             thin3d      = flags.view3dAs2dArray;
1824     const BOOL_32             linear      = IsLinear(swizzle);
1825     const BOOL_32             blk256B     = IsBlock256b(swizzle);
1826     const BOOL_32             isNonPrtXor = IsNonPrtXor(swizzle);
1827     const BOOL_32             prt         = flags.prt;
1828 
1829     // Misc check
1830     if (msaa && (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numSamples)))
1831     {
1832         // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
1833         ADDR_ASSERT_ALWAYS();
1834         valid = FALSE;
1835     }
1836 
1837     if (display && (IsValidDisplaySwizzleMode(pIn) == FALSE))
1838     {
1839         ADDR_ASSERT_ALWAYS();
1840         valid = FALSE;
1841     }
1842 
1843     if ((pIn->bpp == 96) && (linear == FALSE))
1844     {
1845         ADDR_ASSERT_ALWAYS();
1846         valid = FALSE;
1847     }
1848 
1849     const UINT_32 swizzleMask = 1 << swizzle;
1850 
1851     // Resource type check
1852     if (tex1d)
1853     {
1854         if ((swizzleMask & Gfx11Rsrc1dSwModeMask) == 0)
1855         {
1856             ADDR_ASSERT_ALWAYS();
1857             valid = FALSE;
1858         }
1859     }
1860     else if (tex2d)
1861     {
1862         if ((swizzleMask & Gfx11Rsrc2dSwModeMask) == 0)
1863         {
1864             ADDR_ASSERT_ALWAYS();
1865             valid = FALSE;
1866         }
1867         else if (prt && ((swizzleMask & Gfx11Rsrc2dPrtSwModeMask) == 0))
1868         {
1869             ADDR_ASSERT_ALWAYS();
1870             valid = FALSE;
1871         }
1872     }
1873     else if (tex3d)
1874     {
1875         if (((swizzleMask & Gfx11Rsrc3dSwModeMask) == 0) ||
1876             (prt && ((swizzleMask & Gfx11Rsrc3dPrtSwModeMask) == 0)) ||
1877             (thin3d && ((swizzleMask & Gfx11Rsrc3dThinSwModeMask) == 0)))
1878         {
1879             ADDR_ASSERT_ALWAYS();
1880             valid = FALSE;
1881         }
1882     }
1883 
1884     // Swizzle type check
1885     if (linear)
1886     {
1887         if (zbuffer || msaa || (pIn->bpp == 0) || ((pIn->bpp % 8) != 0))
1888         {
1889             ADDR_ASSERT_ALWAYS();
1890             valid = FALSE;
1891         }
1892     }
1893     else if (IsZOrderSwizzle(swizzle))
1894     {
1895         if ((pIn->bpp > 64)                         ||
1896             (msaa && (color || (pIn->bpp > 32)))    ||
1897             ElemLib::IsBlockCompressed(pIn->format) ||
1898             ElemLib::IsMacroPixelPacked(pIn->format))
1899         {
1900             ADDR_ASSERT_ALWAYS();
1901             valid = FALSE;
1902         }
1903     }
1904     else if (IsStandardSwizzle(rsrcType, swizzle))
1905     {
1906         if (zbuffer || msaa)
1907         {
1908             ADDR_ASSERT_ALWAYS();
1909             valid = FALSE;
1910         }
1911     }
1912     else if (IsDisplaySwizzle(rsrcType, swizzle))
1913     {
1914         if (zbuffer || msaa)
1915         {
1916             ADDR_ASSERT_ALWAYS();
1917             valid = FALSE;
1918         }
1919     }
1920     else if (IsRtOptSwizzle(swizzle))
1921     {
1922         if (zbuffer)
1923         {
1924             ADDR_ASSERT_ALWAYS();
1925             valid = FALSE;
1926         }
1927     }
1928     else
1929     {
1930         ADDR_ASSERT_ALWAYS();
1931         valid = FALSE;
1932     }
1933 
1934     // Block type check
1935     if (blk256B)
1936     {
1937         if (zbuffer || tex3d || msaa)
1938         {
1939             ADDR_ASSERT_ALWAYS();
1940             valid = FALSE;
1941         }
1942     }
1943 
1944     return valid;
1945 }
1946 
1947 /**
1948 ************************************************************************************************************************
1949 *   Gfx11Lib::HwlComputeSurfaceInfoSanityCheck
1950 *
1951 *   @brief
1952 *       Compute surface info sanity check
1953 *
1954 *   @return
1955 *       Offset
1956 ************************************************************************************************************************
1957 */
HwlComputeSurfaceInfoSanityCheck(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn) const1958 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceInfoSanityCheck(
1959     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn     ///< [in] input structure
1960     ) const
1961 {
1962     return ValidateNonSwModeParams(pIn) && ValidateSwModeParams(pIn) ? ADDR_OK : ADDR_INVALIDPARAMS;
1963 }
1964 
1965 /**
1966 ************************************************************************************************************************
1967 *   Gfx11Lib::HwlGetPreferredSurfaceSetting
1968 *
1969 *   @brief
1970 *       Internal function to get suggested surface information for cliet to use
1971 *
1972 *   @return
1973 *       ADDR_E_RETURNCODE
1974 ************************************************************************************************************************
1975 */
HwlGetPreferredSurfaceSetting(const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT * pIn,ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT * pOut) const1976 ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
1977     const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,  ///< [in] input structure
1978     ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut  ///< [out] output structure
1979     ) const
1980 {
1981     ADDR_E_RETURNCODE returnCode = ADDR_OK;
1982 
1983     if (pIn->flags.fmask)
1984     {
1985         // There is no FMASK for GFX11 ASICs.
1986         ADDR_ASSERT_ALWAYS();
1987 
1988         returnCode = ADDR_INVALIDPARAMS;
1989     }
1990     else
1991     {
1992         UINT_32 bpp    = pIn->bpp;
1993         UINT_32 width  = Max(pIn->width, 1u);
1994         UINT_32 height = Max(pIn->height, 1u);
1995 
1996         // Set format to INVALID will skip this conversion
1997         if (pIn->format != ADDR_FMT_INVALID)
1998         {
1999             ElemMode elemMode = ADDR_UNCOMPRESSED;
2000             UINT_32 expandX, expandY;
2001 
2002             // Get compression/expansion factors and element mode which indicates compression/expansion
2003             bpp = GetElemLib()->GetBitsPerPixel(pIn->format,
2004                                                 &elemMode,
2005                                                 &expandX,
2006                                                 &expandY);
2007 
2008             UINT_32 basePitch = 0;
2009             GetElemLib()->AdjustSurfaceInfo(elemMode,
2010                                             expandX,
2011                                             expandY,
2012                                             &bpp,
2013                                             &basePitch,
2014                                             &width,
2015                                             &height);
2016         }
2017 
2018         const UINT_32 numSlices    = Max(pIn->numSlices,    1u);
2019         const UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u);
2020         const UINT_32 numSamples   = Max(pIn->numSamples,   1u);
2021         const BOOL_32 msaa         = numSamples > 1;
2022 
2023         // Pre sanity check on non swizzle mode parameters
2024         ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
2025         localIn.flags        = pIn->flags;
2026         localIn.resourceType = pIn->resourceType;
2027         localIn.format       = pIn->format;
2028         localIn.bpp          = bpp;
2029         localIn.width        = width;
2030         localIn.height       = height;
2031         localIn.numSlices    = numSlices;
2032         localIn.numMipLevels = numMipLevels;
2033         localIn.numSamples   = numSamples;
2034         localIn.numFrags     = numSamples;
2035 
2036         if (ValidateNonSwModeParams(&localIn))
2037         {
2038             // Forbid swizzle mode(s) by client setting
2039             ADDR2_SWMODE_SET allowedSwModeSet = {};
2040             allowedSwModeSet.value |= pIn->forbiddenBlock.linear ? 0 : Gfx11LinearSwModeMask;
2041             allowedSwModeSet.value |= pIn->forbiddenBlock.micro  ? 0 : Gfx11Blk256BSwModeMask;
2042             allowedSwModeSet.value |=
2043                 pIn->forbiddenBlock.macroThin4KB ? 0 :
2044                 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? 0 : Gfx11Blk4KBSwModeMask);
2045             allowedSwModeSet.value |=
2046                 pIn->forbiddenBlock.macroThick4KB ? 0 :
2047                 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThick4KBSwModeMask : 0);
2048             allowedSwModeSet.value |=
2049                 pIn->forbiddenBlock.macroThin64KB ? 0 :
2050                 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThin64KBSwModeMask : Gfx11Blk64KBSwModeMask);
2051             allowedSwModeSet.value |=
2052                 pIn->forbiddenBlock.macroThick64KB ? 0 :
2053                 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThick64KBSwModeMask : 0);
2054             allowedSwModeSet.value |=
2055                 pIn->forbiddenBlock.gfx11.thin256KB ? 0 :
2056                 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThin256KBSwModeMask : Gfx11Blk256KBSwModeMask);
2057             allowedSwModeSet.value |=
2058                 pIn->forbiddenBlock.gfx11.thick256KB ? 0 :
2059                 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThick256KBSwModeMask : 0);
2060 
2061             if (pIn->preferredSwSet.value != 0)
2062             {
2063                 allowedSwModeSet.value &= pIn->preferredSwSet.sw_Z ? ~0 : ~Gfx11ZSwModeMask;
2064                 allowedSwModeSet.value &= pIn->preferredSwSet.sw_S ? ~0 : ~Gfx11StandardSwModeMask;
2065                 allowedSwModeSet.value &= pIn->preferredSwSet.sw_D ? ~0 : ~Gfx11DisplaySwModeMask;
2066                 allowedSwModeSet.value &= pIn->preferredSwSet.sw_R ? ~0 : ~Gfx11RenderSwModeMask;
2067             }
2068 
2069             if (pIn->noXor)
2070             {
2071                 allowedSwModeSet.value &= ~Gfx11XorSwModeMask;
2072             }
2073 
2074             if (pIn->maxAlign > 0)
2075             {
2076                 if (pIn->maxAlign < Size256K)
2077                 {
2078                     allowedSwModeSet.value &= ~Gfx11Blk256KBSwModeMask;
2079                 }
2080 
2081                 if (pIn->maxAlign < Size64K)
2082                 {
2083                     allowedSwModeSet.value &= ~Gfx11Blk64KBSwModeMask;
2084                 }
2085 
2086                 if (pIn->maxAlign < Size4K)
2087                 {
2088                     allowedSwModeSet.value &= ~Gfx11Blk4KBSwModeMask;
2089                 }
2090 
2091                 if (pIn->maxAlign < Size256)
2092                 {
2093                     allowedSwModeSet.value &= ~Gfx11Blk256BSwModeMask;
2094                 }
2095             }
2096 
2097             // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
2098             switch (pIn->resourceType)
2099             {
2100                 case ADDR_RSRC_TEX_1D:
2101                     allowedSwModeSet.value &= Gfx11Rsrc1dSwModeMask;
2102                     break;
2103 
2104                 case ADDR_RSRC_TEX_2D:
2105                     allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc2dPrtSwModeMask : Gfx11Rsrc2dSwModeMask;
2106                     break;
2107 
2108                 case ADDR_RSRC_TEX_3D:
2109                     allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc3dPrtSwModeMask : Gfx11Rsrc3dSwModeMask;
2110 
2111                     if (pIn->flags.view3dAs2dArray)
2112                     {
2113                         allowedSwModeSet.value &= Gfx11Rsrc3dThinSwModeMask;
2114                     }
2115                     break;
2116 
2117                 default:
2118                     ADDR_ASSERT_ALWAYS();
2119                     allowedSwModeSet.value = 0;
2120                     break;
2121             }
2122 
2123             if (ElemLib::IsBlockCompressed(pIn->format)  ||
2124                 ElemLib::IsMacroPixelPacked(pIn->format) ||
2125                 (bpp > 64)                               ||
2126                 (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))
2127             {
2128                 allowedSwModeSet.value &= ~Gfx11ZSwModeMask;
2129             }
2130 
2131             if (pIn->format == ADDR_FMT_32_32_32)
2132             {
2133                 allowedSwModeSet.value &= Gfx11LinearSwModeMask;
2134             }
2135 
2136             if (msaa)
2137             {
2138                 allowedSwModeSet.value &= Gfx11MsaaSwModeMask;
2139             }
2140 
2141             if (pIn->flags.depth || pIn->flags.stencil)
2142             {
2143                 allowedSwModeSet.value &= Gfx11ZSwModeMask;
2144             }
2145 
2146             if (pIn->flags.display)
2147             {
2148                 allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp);
2149             }
2150 
2151             if (allowedSwModeSet.value != 0)
2152             {
2153 #if DEBUG
2154                 // Post sanity check, at least AddrLib should accept the output generated by its own
2155                 UINT_32 validateSwModeSet = allowedSwModeSet.value;
2156 
2157                 for (UINT_32 i = 0; validateSwModeSet != 0; i++)
2158                 {
2159                     if (validateSwModeSet & 1)
2160                     {
2161                         localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);
2162                         ADDR_ASSERT(ValidateSwModeParams(&localIn));
2163                     }
2164 
2165                     validateSwModeSet >>= 1;
2166                 }
2167 #endif
2168 
2169                 pOut->resourceType   = pIn->resourceType;
2170                 pOut->validSwModeSet = allowedSwModeSet;
2171                 pOut->canXor         = (allowedSwModeSet.value & Gfx11XorSwModeMask) ? TRUE : FALSE;
2172 
2173                 GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &(pOut->validBlockSet));
2174                 GetAllowedSwSet(allowedSwModeSet, &(pOut->validSwTypeSet));
2175 
2176                 pOut->clientPreferredSwSet = pIn->preferredSwSet;
2177 
2178                 if (pOut->clientPreferredSwSet.value == 0)
2179                 {
2180                     pOut->clientPreferredSwSet.value = AddrSwSetAll;
2181                 }
2182 
2183                 // Apply optional restrictions
2184                 if (pIn->flags.needEquation)
2185                 {
2186                     UINT_32 components = pIn->flags.allowExtEquation ?  ADDR_MAX_EQUATION_COMP :
2187                                                                         ADDR_MAX_LEGACY_EQUATION_COMP;
2188                     FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);
2189                 }
2190 
2191                 if (allowedSwModeSet.value == Gfx11LinearSwModeMask)
2192                 {
2193                     pOut->swizzleMode = ADDR_SW_LINEAR;
2194                 }
2195                 else
2196                 {
2197                     const BOOL_32 computeMinSize = (pIn->flags.minimizeAlign == 1) || (pIn->memoryBudget >= 1.0);
2198 
2199                     if ((height > 1) && (computeMinSize == FALSE))
2200                     {
2201                         // Always ignore linear swizzle mode if:
2202                         // 1. This is a (2D/3D) resource with height > 1
2203                         // 2. Client doesn't require computing minimize size
2204                         allowedSwModeSet.swLinear = 0;
2205                     }
2206 
2207                     ADDR2_BLOCK_SET allowedBlockSet = {};
2208                     GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &allowedBlockSet);
2209 
2210                     // Determine block size if there are 2 or more block type candidates
2211                     if (IsPow2(allowedBlockSet.value) == FALSE)
2212                     {
2213                         AddrSwizzleMode swMode[AddrBlockMaxTiledType] = {};
2214 
2215                         swMode[AddrBlockLinear] = ADDR_SW_LINEAR;
2216 
2217                         if (pOut->resourceType == ADDR_RSRC_TEX_3D)
2218                         {
2219                             swMode[AddrBlockThick4KB]   = ADDR_SW_4KB_S_X;
2220                             swMode[AddrBlockThin64KB]   = ADDR_SW_64KB_R_X;
2221                             swMode[AddrBlockThick64KB]  = ADDR_SW_64KB_S_X;
2222                             swMode[AddrBlockThin256KB]  = ADDR_SW_256KB_R_X;
2223                             swMode[AddrBlockThick256KB] = ADDR_SW_256KB_S_X;
2224                         }
2225                         else
2226                         {
2227                             swMode[AddrBlockMicro]     = ADDR_SW_256B_D;
2228                             swMode[AddrBlockThin4KB]   = ADDR_SW_4KB_D_X;
2229                             swMode[AddrBlockThin64KB]  = ADDR_SW_64KB_D_X;
2230                             swMode[AddrBlockThin256KB] = ADDR_SW_256KB_D_X;
2231                         }
2232 
2233                         UINT_64 padSize[AddrBlockMaxTiledType] = {};
2234 
2235                         const UINT_32 ratioLow           = computeMinSize ? 1 : (pIn->flags.opt4space ? 3 : 2);
2236                         const UINT_32 ratioHi            = computeMinSize ? 1 : (pIn->flags.opt4space ? 2 : 1);
2237                         const UINT_64 sizeAlignInElement = Max(NextPow2(pIn->minSizeAlign) / (bpp >> 3), 1u);
2238                         UINT_32       minSizeBlk         = AddrBlockMicro;
2239                         UINT_64       minSize            = 0;
2240 
2241                         ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};
2242 
2243                         for (UINT_32 i = AddrBlockLinear; i < AddrBlockMaxTiledType; i++)
2244                         {
2245                             if (Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<::AddrBlockType>(i)))
2246                             {
2247                                 localIn.swizzleMode = swMode[i];
2248 
2249                                 if (localIn.swizzleMode == ADDR_SW_LINEAR)
2250                                 {
2251                                     returnCode = HwlComputeSurfaceInfoLinear(&localIn, &localOut);
2252                                 }
2253                                 else
2254                                 {
2255                                     returnCode = HwlComputeSurfaceInfoTiled(&localIn, &localOut);
2256                                 }
2257 
2258                                 if (returnCode == ADDR_OK)
2259                                 {
2260                                     padSize[i] = localOut.surfSize;
2261 
2262                                     if ((minSize == 0) ||
2263                                         Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], ratioLow, ratioHi))
2264                                     {
2265                                         minSize    = padSize[i];
2266                                         minSizeBlk = i;
2267                                     }
2268                                 }
2269                                 else
2270                                 {
2271                                     ADDR_ASSERT_ALWAYS();
2272                                     break;
2273                                 }
2274                             }
2275                         }
2276 
2277                         if (pIn->memoryBudget > 1.0)
2278                         {
2279                             // If minimum size is given by swizzle mode with bigger-block type, then don't ever check
2280                             // smaller-block type again in coming loop
2281                             switch (minSizeBlk)
2282                             {
2283                                 case AddrBlockThick256KB:
2284                                     allowedBlockSet.gfx11.thin256KB = 0;
2285                                 case AddrBlockThin256KB:
2286                                     allowedBlockSet.macroThick64KB = 0;
2287                                 case AddrBlockThick64KB:
2288                                     allowedBlockSet.macroThin64KB = 0;
2289                                 case AddrBlockThin64KB:
2290                                     allowedBlockSet.macroThick4KB = 0;
2291                                 case AddrBlockThick4KB:
2292                                     allowedBlockSet.macroThin4KB = 0;
2293                                 case AddrBlockThin4KB:
2294                                     allowedBlockSet.micro  = 0;
2295                                 case AddrBlockMicro:
2296                                     allowedBlockSet.linear = 0;
2297                                 case AddrBlockLinear:
2298                                     break;
2299 
2300                                 default:
2301                                     ADDR_ASSERT_ALWAYS();
2302                                     break;
2303                             }
2304 
2305                             for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)
2306                             {
2307                                 if ((i != minSizeBlk) &&
2308                                     Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<::AddrBlockType>(i)))
2309                                 {
2310                                     if (Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], 0, 0, pIn->memoryBudget) == FALSE)
2311                                     {
2312                                         // Clear the block type if the memory waste is unacceptable
2313                                         allowedBlockSet.value &= ~(1u << (i - 1));
2314                                     }
2315                                 }
2316                             }
2317 
2318                             // Remove linear block type if 2 or more block types are allowed
2319                             if (IsPow2(allowedBlockSet.value) == FALSE)
2320                             {
2321                                 allowedBlockSet.linear = 0;
2322                             }
2323 
2324                             // Select the biggest allowed block type
2325                             minSizeBlk = Log2NonPow2(allowedBlockSet.value) + 1;
2326 
2327                             if (minSizeBlk == static_cast<UINT_32>(AddrBlockMaxTiledType))
2328                             {
2329                                 minSizeBlk = AddrBlockLinear;
2330                             }
2331                         }
2332 
2333                         switch (minSizeBlk)
2334                         {
2335                             case AddrBlockLinear:
2336                                 allowedSwModeSet.value &= Gfx11LinearSwModeMask;
2337                                 break;
2338 
2339                             case AddrBlockMicro:
2340                                 ADDR_ASSERT(pOut->resourceType != ADDR_RSRC_TEX_3D);
2341                                 allowedSwModeSet.value &= Gfx11Blk256BSwModeMask;
2342                                 break;
2343 
2344                             case AddrBlockThin4KB:
2345                                 ADDR_ASSERT(pOut->resourceType != ADDR_RSRC_TEX_3D);
2346                                 allowedSwModeSet.value &= Gfx11Blk4KBSwModeMask;
2347                                 break;
2348 
2349                             case AddrBlockThick4KB:
2350                                 ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);
2351                                 allowedSwModeSet.value &= Gfx11Rsrc3dThick4KBSwModeMask;
2352                                 break;
2353 
2354                             case AddrBlockThin64KB:
2355                                 allowedSwModeSet.value &= (pOut->resourceType == ADDR_RSRC_TEX_3D) ?
2356                                                           Gfx11Rsrc3dThin64KBSwModeMask : Gfx11Blk64KBSwModeMask;
2357                                 break;
2358 
2359                             case AddrBlockThick64KB:
2360                                 ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);
2361                                 allowedSwModeSet.value &= Gfx11Rsrc3dThick64KBSwModeMask;
2362                                 break;
2363 
2364                             case AddrBlockThin256KB:
2365                                 allowedSwModeSet.value &= (pOut->resourceType == ADDR_RSRC_TEX_3D) ?
2366                                                           Gfx11Rsrc3dThin256KBSwModeMask : Gfx11Blk256KBSwModeMask;
2367                                 break;
2368 
2369                             case AddrBlockThick256KB:
2370                                 ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);
2371                                 allowedSwModeSet.value &= Gfx11Rsrc3dThick256KBSwModeMask;
2372                                 break;
2373 
2374                             default:
2375                                 ADDR_ASSERT_ALWAYS();
2376                                 allowedSwModeSet.value = 0;
2377                                 break;
2378                         }
2379                     }
2380 
2381                     // Block type should be determined.
2382                     GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &allowedBlockSet);
2383                     ADDR_ASSERT(IsPow2(allowedBlockSet.value));
2384 
2385                     ADDR2_SWTYPE_SET allowedSwSet = {};
2386                     GetAllowedSwSet(allowedSwModeSet, &allowedSwSet);
2387 
2388                     // Determine swizzle type if there are 2 or more swizzle type candidates
2389                     if ((allowedSwSet.value != 0) && (IsPow2(allowedSwSet.value) == FALSE))
2390                     {
2391                         if (ElemLib::IsBlockCompressed(pIn->format))
2392                         {
2393                             if (allowedSwSet.sw_D)
2394                             {
2395                                 allowedSwModeSet.value &= Gfx11DisplaySwModeMask;
2396                             }
2397                             else if (allowedSwSet.sw_S)
2398                             {
2399                                 allowedSwModeSet.value &= Gfx11StandardSwModeMask;
2400                             }
2401                             else
2402                             {
2403                                 ADDR_ASSERT(allowedSwSet.sw_R);
2404                                 allowedSwModeSet.value &= Gfx11RenderSwModeMask;
2405                             }
2406                         }
2407                         else if (ElemLib::IsMacroPixelPacked(pIn->format))
2408                         {
2409                             if (allowedSwSet.sw_S)
2410                             {
2411                                 allowedSwModeSet.value &= Gfx11StandardSwModeMask;
2412                             }
2413                             else if (allowedSwSet.sw_D)
2414                             {
2415                                 allowedSwModeSet.value &= Gfx11DisplaySwModeMask;
2416                             }
2417                             else
2418                             {
2419                                 ADDR_ASSERT(allowedSwSet.sw_R);
2420                                 allowedSwModeSet.value &= Gfx11RenderSwModeMask;
2421                             }
2422                         }
2423                         else if (pIn->resourceType == ADDR_RSRC_TEX_3D)
2424                         {
2425                             if (pIn->flags.color && allowedSwSet.sw_R)
2426                             {
2427                                 allowedSwModeSet.value &= Gfx11RenderSwModeMask;
2428                             }
2429                             else if (allowedSwSet.sw_S)
2430                             {
2431                                 allowedSwModeSet.value &= Gfx11StandardSwModeMask;
2432                             }
2433                             else if (allowedSwSet.sw_D)
2434                             {
2435                                 allowedSwModeSet.value &= Gfx11DisplaySwModeMask;
2436                             }
2437                             else
2438                             {
2439                                 ADDR_ASSERT(allowedSwSet.sw_Z);
2440                                 allowedSwModeSet.value &= Gfx11ZSwModeMask;
2441                             }
2442                         }
2443                         else
2444                         {
2445                             if (allowedSwSet.sw_R)
2446                             {
2447                                 allowedSwModeSet.value &= Gfx11RenderSwModeMask;
2448                             }
2449                             else if (allowedSwSet.sw_D)
2450                             {
2451                                 allowedSwModeSet.value &= Gfx11DisplaySwModeMask;
2452                             }
2453                             else if (allowedSwSet.sw_Z)
2454                             {
2455                                 allowedSwModeSet.value &= Gfx11ZSwModeMask;
2456                             }
2457                             else
2458                             {
2459                                 ADDR_ASSERT_ALWAYS();
2460                             }
2461                         }
2462 
2463                         // Swizzle type should be determined.
2464                         GetAllowedSwSet(allowedSwModeSet, &allowedSwSet);
2465                         ADDR_ASSERT(IsPow2(allowedSwSet.value));
2466                     }
2467 
2468                     // Determine swizzle mode now. Always select the "largest" swizzle mode for a given block type +
2469                     // swizzle type combination. E.g, for AddrBlockThin64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's
2470                     // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).
2471                     pOut->swizzleMode = static_cast<AddrSwizzleMode>(Log2NonPow2(allowedSwModeSet.value));
2472                 }
2473             }
2474             else
2475             {
2476                 // Invalid combination...
2477                 ADDR_ASSERT_ALWAYS();
2478                 returnCode = ADDR_INVALIDPARAMS;
2479             }
2480         }
2481         else
2482         {
2483             // Invalid combination...
2484             ADDR_ASSERT_ALWAYS();
2485             returnCode = ADDR_INVALIDPARAMS;
2486         }
2487     }
2488 
2489     return returnCode;
2490 }
2491 
2492 /**
2493 ************************************************************************************************************************
2494 *   Gfx11Lib::HwlGetPossibleSwizzleModes
2495 *
2496 *   @brief
2497 *       Returns a list of swizzle modes that are valid from the hardware's perspective for the client to choose from
2498 *
2499 *   @return
2500 *       ADDR_E_RETURNCODE
2501 ************************************************************************************************************************
2502 */
HwlGetPossibleSwizzleModes(const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT * pIn,ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT * pOut) const2503 ADDR_E_RETURNCODE Gfx11Lib::HwlGetPossibleSwizzleModes(
2504     const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,  ///< [in] input structure
2505     ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT*      pOut  ///< [out] output structure
2506     ) const
2507 {
2508     ADDR_E_RETURNCODE returnCode = ADDR_OK;
2509 
2510     if (pIn->flags.fmask)
2511     {
2512         // There is no FMASK for GFX11 ASICs.
2513         ADDR_ASSERT_ALWAYS();
2514 
2515         returnCode = ADDR_INVALIDPARAMS;
2516     }
2517     else
2518     {
2519         UINT_32 bpp    = pIn->bpp;
2520         UINT_32 width  = Max(pIn->width, 1u);
2521         UINT_32 height = Max(pIn->height, 1u);
2522 
2523         // Set format to INVALID will skip this conversion
2524         if (pIn->format != ADDR_FMT_INVALID)
2525         {
2526             ElemMode elemMode = ADDR_UNCOMPRESSED;
2527             UINT_32 expandX, expandY;
2528 
2529             // Get compression/expansion factors and element mode which indicates compression/expansion
2530             bpp = GetElemLib()->GetBitsPerPixel(pIn->format,
2531                 &elemMode,
2532                 &expandX,
2533                 &expandY);
2534 
2535             UINT_32 basePitch = 0;
2536             GetElemLib()->AdjustSurfaceInfo(elemMode,
2537                 expandX,
2538                 expandY,
2539                 &bpp,
2540                 &basePitch,
2541                 &width,
2542                 &height);
2543         }
2544 
2545         const UINT_32 numSlices    = Max(pIn->numSlices, 1u);
2546         const UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u);
2547         const UINT_32 numSamples   = Max(pIn->numSamples, 1u);
2548         const BOOL_32 msaa         = numSamples > 1;
2549 
2550         // Pre sanity check on non swizzle mode parameters
2551         ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
2552         localIn.flags = pIn->flags;
2553         localIn.resourceType = pIn->resourceType;
2554         localIn.format = pIn->format;
2555         localIn.bpp = bpp;
2556         localIn.width = width;
2557         localIn.height = height;
2558         localIn.numSlices = numSlices;
2559         localIn.numMipLevels = numMipLevels;
2560         localIn.numSamples = numSamples;
2561         localIn.numFrags = numSamples;
2562 
2563         if (ValidateNonSwModeParams(&localIn))
2564         {
2565             // Allow appropriate swizzle modes by default
2566             ADDR2_SWMODE_SET allowedSwModeSet = {};
2567             allowedSwModeSet.value |= Gfx11LinearSwModeMask | Gfx11Blk256BSwModeMask;
2568             if (pIn->resourceType == ADDR_RSRC_TEX_3D)
2569             {
2570                 allowedSwModeSet.value |= Gfx11Rsrc3dThick4KBSwModeMask  |
2571                                           Gfx11Rsrc3dThin64KBSwModeMask  |
2572                                           Gfx11Rsrc3dThick64KBSwModeMask |
2573                                           Gfx11Rsrc3dThin256KBSwModeMask |
2574                                           Gfx11Rsrc3dThick256KBSwModeMask;
2575             }
2576             else
2577             {
2578                 allowedSwModeSet.value |= Gfx11Blk4KBSwModeMask | Gfx11Blk64KBSwModeMask | Gfx11Blk256KBSwModeMask;
2579             }
2580 
2581             // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
2582             switch (pIn->resourceType)
2583             {
2584             case ADDR_RSRC_TEX_1D:
2585                 allowedSwModeSet.value &= Gfx11Rsrc1dSwModeMask;
2586                 break;
2587 
2588             case ADDR_RSRC_TEX_2D:
2589                 allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc2dPrtSwModeMask : Gfx11Rsrc2dSwModeMask;
2590                 break;
2591 
2592             case ADDR_RSRC_TEX_3D:
2593                 allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc3dPrtSwModeMask : Gfx11Rsrc3dSwModeMask;
2594 
2595                 if (pIn->flags.view3dAs2dArray)
2596                 {
2597                     allowedSwModeSet.value &= Gfx11Rsrc3dThinSwModeMask;
2598                 }
2599                 break;
2600 
2601             default:
2602                 ADDR_ASSERT_ALWAYS();
2603                 allowedSwModeSet.value = 0;
2604                 break;
2605             }
2606 
2607             // TODO: figure out if following restrictions are correct on GFX11...
2608             if (ElemLib::IsBlockCompressed(pIn->format) ||
2609                 ElemLib::IsMacroPixelPacked(pIn->format) ||
2610                 (bpp > 64) ||
2611                 (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))
2612             {
2613                 allowedSwModeSet.value &= ~Gfx11ZSwModeMask;
2614             }
2615 
2616             if (pIn->format == ADDR_FMT_32_32_32)
2617             {
2618                 allowedSwModeSet.value &= Gfx11LinearSwModeMask;
2619             }
2620 
2621             if (msaa)
2622             {
2623                 allowedSwModeSet.value &= Gfx11MsaaSwModeMask;
2624             }
2625 
2626             if (pIn->flags.depth || pIn->flags.stencil)
2627             {
2628                 allowedSwModeSet.value &= Gfx11ZSwModeMask;
2629             }
2630 
2631             if (pIn->flags.display)
2632             {
2633                 allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp);
2634             }
2635 
2636             if (allowedSwModeSet.value != 0)
2637             {
2638 #if DEBUG
2639                 // Post sanity check, at least AddrLib should accept the output generated by its own
2640                 UINT_32 validateSwModeSet = allowedSwModeSet.value;
2641 
2642                 for (UINT_32 i = 0; validateSwModeSet != 0; i++)
2643                 {
2644                     if (validateSwModeSet & 1)
2645                     {
2646                         localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);
2647                         ADDR_ASSERT(ValidateSwModeParams(&localIn));
2648                     }
2649 
2650                     validateSwModeSet >>= 1;
2651                 }
2652 #endif
2653 
2654                 pOut->resourceType = pIn->resourceType;
2655                 pOut->clientPreferredSwSet = pIn->preferredSwSet;
2656 
2657                 if (pOut->clientPreferredSwSet.value == 0)
2658                 {
2659                     pOut->clientPreferredSwSet.value = AddrSwSetAll;
2660                 }
2661 
2662                 if (pIn->flags.needEquation)
2663                 {
2664                     UINT_32 components = pIn->flags.allowExtEquation ?  ADDR_MAX_EQUATION_COMP :
2665                                                                         ADDR_MAX_LEGACY_EQUATION_COMP;
2666                     FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);
2667                 }
2668 
2669                 pOut->validSwModeSet = allowedSwModeSet;
2670                 pOut->canXor = (allowedSwModeSet.value & Gfx11XorSwModeMask) ? TRUE : FALSE;
2671             }
2672             else
2673             {
2674                 // Invalid combination...
2675                 ADDR_ASSERT_ALWAYS();
2676                 returnCode = ADDR_INVALIDPARAMS;
2677             }
2678         }
2679         else
2680         {
2681             // Invalid combination...
2682             ADDR_ASSERT_ALWAYS();
2683             returnCode = ADDR_INVALIDPARAMS;
2684         }
2685     }
2686 
2687     return returnCode;
2688 }
2689 
2690 /**
2691 ************************************************************************************************************************
2692 *   Gfx11Lib::HwlGetAllowedBlockSet
2693 *
2694 *   @brief
2695 *       Returns the set of allowed block sizes given the allowed swizzle modes and resource type
2696 *
2697 *   @return
2698 *       ADDR_E_RETURNCODE
2699 ************************************************************************************************************************
2700 */
HwlGetAllowedBlockSet(ADDR2_SWMODE_SET allowedSwModeSet,AddrResourceType rsrcType,ADDR2_BLOCK_SET * pAllowedBlockSet) const2701 ADDR_E_RETURNCODE Gfx11Lib::HwlGetAllowedBlockSet(
2702     ADDR2_SWMODE_SET allowedSwModeSet,  ///< [in] allowed swizzle modes
2703     AddrResourceType rsrcType,          ///< [in] resource type
2704     ADDR2_BLOCK_SET* pAllowedBlockSet   ///< [out] allowed block sizes
2705     ) const
2706 {
2707     ADDR2_BLOCK_SET allowedBlockSet = {};
2708 
2709     allowedBlockSet.micro  = (allowedSwModeSet.value & Gfx11Blk256BSwModeMask) ? TRUE : FALSE;
2710     allowedBlockSet.linear = (allowedSwModeSet.value & Gfx11LinearSwModeMask)  ? TRUE : FALSE;
2711 
2712     if (rsrcType == ADDR_RSRC_TEX_3D)
2713     {
2714         allowedBlockSet.macroThick4KB    = (allowedSwModeSet.value & Gfx11Rsrc3dThick4KBSwModeMask)   ? TRUE : FALSE;
2715         allowedBlockSet.macroThin64KB    = (allowedSwModeSet.value & Gfx11Rsrc3dThin64KBSwModeMask)   ? TRUE : FALSE;
2716         allowedBlockSet.macroThick64KB   = (allowedSwModeSet.value & Gfx11Rsrc3dThick64KBSwModeMask)  ? TRUE : FALSE;
2717         allowedBlockSet.gfx11.thin256KB  = (allowedSwModeSet.value & Gfx11Rsrc3dThin256KBSwModeMask)  ? TRUE : FALSE;
2718         allowedBlockSet.gfx11.thick256KB = (allowedSwModeSet.value & Gfx11Rsrc3dThick256KBSwModeMask) ? TRUE : FALSE;
2719     }
2720     else
2721     {
2722         allowedBlockSet.macroThin4KB    = (allowedSwModeSet.value & Gfx11Blk4KBSwModeMask)   ? TRUE : FALSE;
2723         allowedBlockSet.macroThin64KB   = (allowedSwModeSet.value & Gfx11Blk64KBSwModeMask)  ? TRUE : FALSE;
2724         allowedBlockSet.gfx11.thin256KB = (allowedSwModeSet.value & Gfx11Blk256KBSwModeMask) ? TRUE : FALSE;
2725     }
2726 
2727     *pAllowedBlockSet = allowedBlockSet;
2728     return ADDR_OK;
2729 }
2730 
2731 /**
2732 ************************************************************************************************************************
2733 *   Gfx11Lib::HwlGetAllowedSwSet
2734 *
2735 *   @brief
2736 *       Returns the set of allowed swizzle types given the allowed swizzle modes
2737 *   @return
2738 *       ADDR_E_RETURNCODE
2739 ************************************************************************************************************************
2740 */
HwlGetAllowedSwSet(ADDR2_SWMODE_SET allowedSwModeSet,ADDR2_SWTYPE_SET * pAllowedSwSet) const2741 ADDR_E_RETURNCODE Gfx11Lib::HwlGetAllowedSwSet(
2742     ADDR2_SWMODE_SET  allowedSwModeSet, ///< [in] allowed swizzle modes
2743     ADDR2_SWTYPE_SET* pAllowedSwSet     ///< [out] allowed swizzle types
2744     ) const
2745 {
2746     ADDR2_SWTYPE_SET allowedSwSet = {};
2747 
2748     allowedSwSet.sw_Z = (allowedSwModeSet.value & Gfx11ZSwModeMask)        ? TRUE : FALSE;
2749     allowedSwSet.sw_S = (allowedSwModeSet.value & Gfx11StandardSwModeMask) ? TRUE : FALSE;
2750     allowedSwSet.sw_D = (allowedSwModeSet.value & Gfx11DisplaySwModeMask)  ? TRUE : FALSE;
2751     allowedSwSet.sw_R = (allowedSwModeSet.value & Gfx11RenderSwModeMask)   ? TRUE : FALSE;
2752 
2753     *pAllowedSwSet = allowedSwSet;
2754     return ADDR_OK;
2755 }
2756 
2757 /**
2758 ************************************************************************************************************************
2759 *   Gfx11Lib::ComputeStereoInfo
2760 *
2761 *   @brief
2762 *       Compute height alignment and right eye pipeBankXor for stereo surface
2763 *
2764 *   @return
2765 *       Error code
2766 *
2767 ************************************************************************************************************************
2768 */
ComputeStereoInfo(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 * pAlignY,UINT_32 * pRightXor) const2769 ADDR_E_RETURNCODE Gfx11Lib::ComputeStereoInfo(
2770     const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,        ///< Compute surface info
2771     UINT_32*                                pAlignY,    ///< Stereo requested additional alignment in Y
2772     UINT_32*                                pRightXor   ///< Right eye xor
2773     ) const
2774 {
2775     ADDR_E_RETURNCODE ret = ADDR_OK;
2776 
2777     *pRightXor = 0;
2778 
2779     if (IsNonPrtXor(pIn->swizzleMode))
2780     {
2781         const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);
2782         const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);
2783         const UINT_32 rsrcType    = static_cast<UINT_32>(pIn->resourceType) - 1;
2784         const UINT_32 swMode      = static_cast<UINT_32>(pIn->swizzleMode);
2785         const UINT_32 eqIndex     = m_equationLookupTable[rsrcType][swMode][elemLog2];
2786 
2787         if (eqIndex != ADDR_INVALID_EQUATION_INDEX)
2788         {
2789             UINT_32 yMax     = 0;
2790             UINT_32 yPosMask = 0;
2791 
2792             // First get "max y bit"
2793             for (UINT_32 i = m_pipeInterleaveLog2; i < blkSizeLog2; i++)
2794             {
2795                 ADDR_ASSERT(m_equationTable[eqIndex].addr[i].valid == 1);
2796 
2797                 if ((m_equationTable[eqIndex].addr[i].channel == 1) &&
2798                     (m_equationTable[eqIndex].addr[i].index > yMax))
2799                 {
2800                     yMax = m_equationTable[eqIndex].addr[i].index;
2801                 }
2802 
2803                 if ((m_equationTable[eqIndex].xor1[i].valid == 1) &&
2804                     (m_equationTable[eqIndex].xor1[i].channel == 1) &&
2805                     (m_equationTable[eqIndex].xor1[i].index > yMax))
2806                 {
2807                     yMax = m_equationTable[eqIndex].xor1[i].index;
2808                 }
2809 
2810                 if ((m_equationTable[eqIndex].xor2[i].valid == 1) &&
2811                     (m_equationTable[eqIndex].xor2[i].channel == 1) &&
2812                     (m_equationTable[eqIndex].xor2[i].index > yMax))
2813                 {
2814                     yMax = m_equationTable[eqIndex].xor2[i].index;
2815                 }
2816             }
2817 
2818             // Then loop again for populating a position mask of "max Y bit"
2819             for (UINT_32 i = m_pipeInterleaveLog2; i < blkSizeLog2; i++)
2820             {
2821                 if ((m_equationTable[eqIndex].addr[i].channel == 1) &&
2822                     (m_equationTable[eqIndex].addr[i].index == yMax))
2823                 {
2824                     yPosMask |= 1u << i;
2825                 }
2826                 else if ((m_equationTable[eqIndex].xor1[i].valid == 1) &&
2827                          (m_equationTable[eqIndex].xor1[i].channel == 1) &&
2828                          (m_equationTable[eqIndex].xor1[i].index == yMax))
2829                 {
2830                     yPosMask |= 1u << i;
2831                 }
2832                 else if ((m_equationTable[eqIndex].xor2[i].valid == 1) &&
2833                          (m_equationTable[eqIndex].xor2[i].channel == 1) &&
2834                          (m_equationTable[eqIndex].xor2[i].index == yMax))
2835                 {
2836                     yPosMask |= 1u << i;
2837                 }
2838             }
2839 
2840             const UINT_32 additionalAlign = 1 << yMax;
2841 
2842             if (additionalAlign >= *pAlignY)
2843             {
2844                 *pAlignY = additionalAlign;
2845 
2846                 const UINT_32 alignedHeight = PowTwoAlign(pIn->height, additionalAlign);
2847 
2848                 if ((alignedHeight >> yMax) & 1)
2849                 {
2850                     *pRightXor = yPosMask >> m_pipeInterleaveLog2;
2851                 }
2852             }
2853         }
2854         else
2855         {
2856             ret = ADDR_INVALIDPARAMS;
2857         }
2858     }
2859 
2860     return ret;
2861 }
2862 
2863 /**
2864 ************************************************************************************************************************
2865 *   Gfx11Lib::HwlComputeSurfaceInfoTiled
2866 *
2867 *   @brief
2868 *       Internal function to calculate alignment for tiled surface
2869 *
2870 *   @return
2871 *       ADDR_E_RETURNCODE
2872 ************************************************************************************************************************
2873 */
HwlComputeSurfaceInfoTiled(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2874 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceInfoTiled(
2875      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
2876      ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
2877      ) const
2878 {
2879     ADDR_E_RETURNCODE ret;
2880 
2881     // Mip chain dimesion and epitch has no meaning in GFX11, set to default value
2882     pOut->mipChainPitch    = 0;
2883     pOut->mipChainHeight   = 0;
2884     pOut->mipChainSlice    = 0;
2885     pOut->epitchIsHeight   = FALSE;
2886 
2887     // Following information will be provided in ComputeSurfaceInfoMacroTiled() if necessary
2888     pOut->mipChainInTail   = FALSE;
2889     pOut->firstMipIdInTail = pIn->numMipLevels;
2890 
2891     if (IsBlock256b(pIn->swizzleMode))
2892     {
2893         ret = ComputeSurfaceInfoMicroTiled(pIn, pOut);
2894     }
2895     else
2896     {
2897         ret = ComputeSurfaceInfoMacroTiled(pIn, pOut);
2898     }
2899 
2900     return ret;
2901 }
2902 
2903 /**
2904 ************************************************************************************************************************
2905 *   Gfx11Lib::ComputeSurfaceInfoMicroTiled
2906 *
2907 *   @brief
2908 *       Internal function to calculate alignment for micro tiled surface
2909 *
2910 *   @return
2911 *       ADDR_E_RETURNCODE
2912 ************************************************************************************************************************
2913 */
ComputeSurfaceInfoMicroTiled(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2914 ADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceInfoMicroTiled(
2915      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
2916      ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
2917      ) const
2918 {
2919     ADDR_E_RETURNCODE ret = ComputeBlockDimensionForSurf(&pOut->blockWidth,
2920                                                          &pOut->blockHeight,
2921                                                          &pOut->blockSlices,
2922                                                          pIn->bpp,
2923                                                          pIn->numSamples,
2924                                                          pIn->resourceType,
2925                                                          pIn->swizzleMode);
2926 
2927     if (ret == ADDR_OK)
2928     {
2929         const UINT_32 blockSize = GetBlockSize(pIn->swizzleMode);
2930 
2931         pOut->pitch     = PowTwoAlign(pIn->width,  pOut->blockWidth);
2932         pOut->height    = PowTwoAlign(pIn->height, pOut->blockHeight);
2933         pOut->numSlices = pIn->numSlices;
2934         pOut->baseAlign = blockSize;
2935 
2936         if (pIn->numMipLevels > 1)
2937         {
2938             const UINT_32 mip0Width    = pIn->width;
2939             const UINT_32 mip0Height   = pIn->height;
2940             UINT_64       mipSliceSize = 0;
2941 
2942             for (INT_32 i = static_cast<INT_32>(pIn->numMipLevels) - 1; i >= 0; i--)
2943             {
2944                 UINT_32 mipWidth, mipHeight;
2945 
2946                 GetMipSize(mip0Width, mip0Height, 1, i, &mipWidth, &mipHeight);
2947 
2948                 const UINT_32 mipActualWidth  = PowTwoAlign(mipWidth,  pOut->blockWidth);
2949                 const UINT_32 mipActualHeight = PowTwoAlign(mipHeight, pOut->blockHeight);
2950 
2951                 if (pOut->pMipInfo != NULL)
2952                 {
2953                     pOut->pMipInfo[i].pitch            = mipActualWidth;
2954                     pOut->pMipInfo[i].height           = mipActualHeight;
2955                     pOut->pMipInfo[i].depth            = 1;
2956                     pOut->pMipInfo[i].offset           = mipSliceSize;
2957                     pOut->pMipInfo[i].mipTailOffset    = 0;
2958                     pOut->pMipInfo[i].macroBlockOffset = mipSliceSize;
2959                 }
2960 
2961                 mipSliceSize += mipActualWidth * mipActualHeight * (pIn->bpp >> 3);
2962             }
2963 
2964             pOut->sliceSize = mipSliceSize;
2965             pOut->surfSize  = mipSliceSize * pOut->numSlices;
2966         }
2967         else
2968         {
2969             pOut->sliceSize = static_cast<UINT_64>(pOut->pitch) * pOut->height * (pIn->bpp >> 3);
2970             pOut->surfSize  = pOut->sliceSize * pOut->numSlices;
2971 
2972             if (pOut->pMipInfo != NULL)
2973             {
2974                 pOut->pMipInfo[0].pitch            = pOut->pitch;
2975                 pOut->pMipInfo[0].height           = pOut->height;
2976                 pOut->pMipInfo[0].depth            = 1;
2977                 pOut->pMipInfo[0].offset           = 0;
2978                 pOut->pMipInfo[0].mipTailOffset    = 0;
2979                 pOut->pMipInfo[0].macroBlockOffset = 0;
2980             }
2981         }
2982 
2983     }
2984 
2985     return ret;
2986 }
2987 
2988 /**
2989 ************************************************************************************************************************
2990 *   Gfx11Lib::ComputeSurfaceInfoMacroTiled
2991 *
2992 *   @brief
2993 *       Internal function to calculate alignment for macro tiled surface
2994 *
2995 *   @return
2996 *       ADDR_E_RETURNCODE
2997 ************************************************************************************************************************
2998 */
ComputeSurfaceInfoMacroTiled(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2999 ADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceInfoMacroTiled(
3000      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
3001      ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
3002      ) const
3003 {
3004     ADDR_E_RETURNCODE returnCode = ComputeBlockDimensionForSurf(&pOut->blockWidth,
3005                                                                 &pOut->blockHeight,
3006                                                                 &pOut->blockSlices,
3007                                                                 pIn->bpp,
3008                                                                 pIn->numSamples,
3009                                                                 pIn->resourceType,
3010                                                                 pIn->swizzleMode);
3011 
3012     if (returnCode == ADDR_OK)
3013     {
3014         UINT_32 heightAlign = pOut->blockHeight;
3015 
3016         if (pIn->flags.qbStereo)
3017         {
3018             UINT_32 rightXor = 0;
3019 
3020             returnCode = ComputeStereoInfo(pIn, &heightAlign, &rightXor);
3021 
3022             if (returnCode == ADDR_OK)
3023             {
3024                 pOut->pStereoInfo->rightSwizzle = rightXor;
3025             }
3026         }
3027 
3028         if (returnCode == ADDR_OK)
3029         {
3030             const UINT_32 blockSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);
3031             const UINT_32 blockSize     = 1 << blockSizeLog2;
3032 
3033             pOut->pitch     = PowTwoAlign(pIn->width,     pOut->blockWidth);
3034             pOut->height    = PowTwoAlign(pIn->height,    heightAlign);
3035             pOut->numSlices = PowTwoAlign(pIn->numSlices, pOut->blockSlices);
3036             pOut->baseAlign = blockSize;
3037 
3038             if (pIn->numMipLevels > 1)
3039             {
3040                 const Dim3d  tailMaxDim         = GetMipTailDim(pIn->resourceType,
3041                                                                 pIn->swizzleMode,
3042                                                                 pOut->blockWidth,
3043                                                                 pOut->blockHeight,
3044                                                                 pOut->blockSlices);
3045                 const UINT_32 mip0Width         = pIn->width;
3046                 const UINT_32 mip0Height        = pIn->height;
3047                 const BOOL_32 isThin            = IsThin(pIn->resourceType, pIn->swizzleMode);
3048                 const UINT_32 mip0Depth         = isThin ? 1 : pIn->numSlices;
3049                 const UINT_32 maxMipsInTail     = GetMaxNumMipsInTail(blockSizeLog2, isThin);
3050                 const UINT_32 index             = Log2(pIn->bpp >> 3);
3051                 UINT_32       firstMipInTail    = pIn->numMipLevels;
3052                 UINT_64       mipChainSliceSize = 0;
3053                 UINT_64       mipSize[MaxMipLevels];
3054                 UINT_64       mipSliceSize[MaxMipLevels];
3055 
3056                 // For htile, we need to make z16 and stencil enter the mip tail at the same time as z32 would
3057                 Dim3d fixedTailMaxDim = tailMaxDim;
3058                 if (IsZOrderSwizzle(pIn->swizzleMode) && (index <= 1))
3059                 {
3060                     fixedTailMaxDim.w /= Block256_2d[index].w / Block256_2d[2].w;
3061                     fixedTailMaxDim.h /= Block256_2d[index].w / Block256_2d[2].w;
3062                 }
3063 
3064                 for (UINT_32 i = 0; i < pIn->numMipLevels; i++)
3065                 {
3066                     UINT_32 mipWidth, mipHeight, mipDepth;
3067 
3068                     GetMipSize(mip0Width, mip0Height, mip0Depth, i, &mipWidth, &mipHeight, &mipDepth);
3069 
3070                     if (IsInMipTail(fixedTailMaxDim, maxMipsInTail, mipWidth, mipHeight, pIn->numMipLevels - i))
3071                     {
3072                         firstMipInTail     = i;
3073                         mipChainSliceSize += blockSize / pOut->blockSlices;
3074                         break;
3075                     }
3076                     else
3077                     {
3078                         const UINT_32 pitch     = PowTwoAlign(mipWidth,  pOut->blockWidth);
3079                         const UINT_32 height    = PowTwoAlign(mipHeight, pOut->blockHeight);
3080                         const UINT_32 depth     = PowTwoAlign(mipDepth,  pOut->blockSlices);
3081                         const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height * (pIn->bpp >> 3);
3082 
3083                         mipSize[i]         = sliceSize * depth;
3084                         mipSliceSize[i]    = sliceSize * pOut->blockSlices;
3085                         mipChainSliceSize += sliceSize;
3086 
3087                         if (pOut->pMipInfo != NULL)
3088                         {
3089                             pOut->pMipInfo[i].pitch  = pitch;
3090                             pOut->pMipInfo[i].height = height;
3091                             pOut->pMipInfo[i].depth  = depth;
3092                         }
3093                     }
3094                 }
3095 
3096                 pOut->sliceSize        = mipChainSliceSize;
3097                 pOut->surfSize         = mipChainSliceSize * pOut->numSlices;
3098                 pOut->mipChainInTail   = (firstMipInTail == 0) ? TRUE : FALSE;
3099                 pOut->firstMipIdInTail = firstMipInTail;
3100 
3101                 if (pOut->pMipInfo != NULL)
3102                 {
3103                     UINT_64 offset         = 0;
3104                     UINT_64 macroBlkOffset = 0;
3105                     UINT_32 tailMaxDepth   = 0;
3106 
3107                     if (firstMipInTail != pIn->numMipLevels)
3108                     {
3109                         UINT_32 mipWidth, mipHeight;
3110 
3111                         GetMipSize(mip0Width, mip0Height, mip0Depth, firstMipInTail,
3112                                    &mipWidth, &mipHeight, &tailMaxDepth);
3113 
3114                         offset         = blockSize * PowTwoAlign(tailMaxDepth, pOut->blockSlices) / pOut->blockSlices;
3115                         macroBlkOffset = blockSize;
3116                     }
3117 
3118                     for (INT_32 i = firstMipInTail - 1; i >= 0; i--)
3119                     {
3120                         pOut->pMipInfo[i].offset           = offset;
3121                         pOut->pMipInfo[i].macroBlockOffset = macroBlkOffset;
3122                         pOut->pMipInfo[i].mipTailOffset    = 0;
3123 
3124                         offset         += mipSize[i];
3125                         macroBlkOffset += mipSliceSize[i];
3126                     }
3127 
3128                     UINT_32 pitch  = tailMaxDim.w;
3129                     UINT_32 height = tailMaxDim.h;
3130                     UINT_32 depth  = isThin ? 1 : PowTwoAlign(tailMaxDepth, Block256_3d[index].d);
3131 
3132                     tailMaxDepth = isThin ? 1 : (depth / Block256_3d[index].d);
3133 
3134                     for (UINT_32 i = firstMipInTail; i < pIn->numMipLevels; i++)
3135                     {
3136                         const UINT_32 m         = maxMipsInTail - 1 - (i - firstMipInTail);
3137                         const UINT_32 mipOffset = (m > 6) ? (16 << m) : (m << 8);
3138 
3139                         pOut->pMipInfo[i].offset           = mipOffset * tailMaxDepth;
3140                         pOut->pMipInfo[i].mipTailOffset    = mipOffset;
3141                         pOut->pMipInfo[i].macroBlockOffset = 0;
3142 
3143                         pOut->pMipInfo[i].pitch  = pitch;
3144                         pOut->pMipInfo[i].height = height;
3145                         pOut->pMipInfo[i].depth  = depth;
3146 
3147                         UINT_32 mipX = ((mipOffset >> 9)  & 1)  |
3148                                        ((mipOffset >> 10) & 2)  |
3149                                        ((mipOffset >> 11) & 4)  |
3150                                        ((mipOffset >> 12) & 8)  |
3151                                        ((mipOffset >> 13) & 16) |
3152                                        ((mipOffset >> 14) & 32);
3153                         UINT_32 mipY = ((mipOffset >> 8)  & 1)  |
3154                                        ((mipOffset >> 9)  & 2)  |
3155                                        ((mipOffset >> 10) & 4)  |
3156                                        ((mipOffset >> 11) & 8)  |
3157                                        ((mipOffset >> 12) & 16) |
3158                                        ((mipOffset >> 13) & 32);
3159 
3160                         if (blockSizeLog2 & 1)
3161                         {
3162                             const UINT_32 temp = mipX;
3163                             mipX = mipY;
3164                             mipY = temp;
3165 
3166                             if (index & 1)
3167                             {
3168                                 mipY = (mipY << 1) | (mipX & 1);
3169                                 mipX = mipX >> 1;
3170                             }
3171                         }
3172 
3173                         if (isThin)
3174                         {
3175                             pOut->pMipInfo[i].mipTailCoordX = mipX * Block256_2d[index].w;
3176                             pOut->pMipInfo[i].mipTailCoordY = mipY * Block256_2d[index].h;
3177                             pOut->pMipInfo[i].mipTailCoordZ = 0;
3178 
3179                             pitch  = Max(pitch  >> 1, Block256_2d[index].w);
3180                             height = Max(height >> 1, Block256_2d[index].h);
3181                             depth  = 1;
3182                         }
3183                         else
3184                         {
3185                             pOut->pMipInfo[i].mipTailCoordX = mipX * Block256_3d[index].w;
3186                             pOut->pMipInfo[i].mipTailCoordY = mipY * Block256_3d[index].h;
3187                             pOut->pMipInfo[i].mipTailCoordZ = 0;
3188 
3189                             pitch  = Max(pitch  >> 1, Block256_3d[index].w);
3190                             height = Max(height >> 1, Block256_3d[index].h);
3191                             depth  = PowTwoAlign(Max(depth  >> 1, 1u), Block256_3d[index].d);
3192                         }
3193                     }
3194                 }
3195             }
3196             else
3197             {
3198                 pOut->sliceSize = static_cast<UINT_64>(pOut->pitch) * pOut->height * (pIn->bpp >> 3) * pIn->numSamples;
3199                 pOut->surfSize  = pOut->sliceSize * pOut->numSlices;
3200 
3201                 if (pOut->pMipInfo != NULL)
3202                 {
3203                     pOut->pMipInfo[0].pitch            = pOut->pitch;
3204                     pOut->pMipInfo[0].height           = pOut->height;
3205                     pOut->pMipInfo[0].depth            = IsTex3d(pIn->resourceType)? pOut->numSlices : 1;
3206                     pOut->pMipInfo[0].offset           = 0;
3207                     pOut->pMipInfo[0].mipTailOffset    = 0;
3208                     pOut->pMipInfo[0].macroBlockOffset = 0;
3209                     pOut->pMipInfo[0].mipTailCoordX    = 0;
3210                     pOut->pMipInfo[0].mipTailCoordY    = 0;
3211                     pOut->pMipInfo[0].mipTailCoordZ    = 0;
3212                 }
3213             }
3214         }
3215     }
3216 
3217     return returnCode;
3218 }
3219 
3220 /**
3221 ************************************************************************************************************************
3222 *   Gfx11Lib::HwlComputeSurfaceAddrFromCoordTiled
3223 *
3224 *   @brief
3225 *       Internal function to calculate address from coord for tiled swizzle surface
3226 *
3227 *   @return
3228 *       ADDR_E_RETURNCODE
3229 ************************************************************************************************************************
3230 */
HwlComputeSurfaceAddrFromCoordTiled(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const3231 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceAddrFromCoordTiled(
3232      const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
3233      ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
3234      ) const
3235 {
3236     ADDR_E_RETURNCODE ret;
3237 
3238     if (IsBlock256b(pIn->swizzleMode))
3239     {
3240         ret = ComputeSurfaceAddrFromCoordMicroTiled(pIn, pOut);
3241     }
3242     else
3243     {
3244         ret = ComputeSurfaceAddrFromCoordMacroTiled(pIn, pOut);
3245     }
3246 
3247     return ret;
3248 }
3249 
3250 /**
3251 ************************************************************************************************************************
3252 *   Gfx11Lib::ComputeOffsetFromEquation
3253 *
3254 *   @brief
3255 *       Compute offset from equation
3256 *
3257 *   @return
3258 *       Offset
3259 ************************************************************************************************************************
3260 */
ComputeOffsetFromEquation(const ADDR_EQUATION * pEq,UINT_32 x,UINT_32 y,UINT_32 z) const3261 UINT_32 Gfx11Lib::ComputeOffsetFromEquation(
3262     const ADDR_EQUATION* pEq,   ///< Equation
3263     UINT_32              x,     ///< x coord in bytes
3264     UINT_32              y,     ///< y coord in pixel
3265     UINT_32              z      ///< z coord in slice
3266     ) const
3267 {
3268     UINT_32 offset = 0;
3269 
3270     for (UINT_32 i = 0; i < pEq->numBits; i++)
3271     {
3272         UINT_32 v = 0;
3273 
3274         for (UINT_32 c = 0; c < pEq->numBitComponents; c++)
3275         {
3276             if (pEq->comps[c][i].valid)
3277             {
3278                 if (pEq->comps[c][i].channel == 0)
3279                 {
3280                     v ^= (x >> pEq->comps[c][i].index) & 1;
3281                 }
3282                 else if (pEq->comps[c][i].channel == 1)
3283                 {
3284                     v ^= (y >> pEq->comps[c][i].index) & 1;
3285                 }
3286                 else
3287                 {
3288                     ADDR_ASSERT(pEq->comps[c][i].channel == 2);
3289                     v ^= (z >> pEq->comps[c][i].index) & 1;
3290                 }
3291             }
3292         }
3293 
3294         offset |= (v << i);
3295     }
3296 
3297     return offset;
3298 }
3299 
3300 /**
3301 ************************************************************************************************************************
3302 *   Gfx11Lib::ComputeOffsetFromSwizzlePattern
3303 *
3304 *   @brief
3305 *       Compute offset from swizzle pattern
3306 *
3307 *   @return
3308 *       Offset
3309 ************************************************************************************************************************
3310 */
ComputeOffsetFromSwizzlePattern(const UINT_64 * pPattern,UINT_32 numBits,UINT_32 x,UINT_32 y,UINT_32 z,UINT_32 s) const3311 UINT_32 Gfx11Lib::ComputeOffsetFromSwizzlePattern(
3312     const UINT_64* pPattern,    ///< Swizzle pattern
3313     UINT_32        numBits,     ///< Number of bits in pattern
3314     UINT_32        x,           ///< x coord in pixel
3315     UINT_32        y,           ///< y coord in pixel
3316     UINT_32        z,           ///< z coord in slice
3317     UINT_32        s            ///< sample id
3318     ) const
3319 {
3320     UINT_32                 offset          = 0;
3321     const ADDR_BIT_SETTING* pSwizzlePattern = reinterpret_cast<const ADDR_BIT_SETTING*>(pPattern);
3322 
3323     for (UINT_32 i = 0; i < numBits; i++)
3324     {
3325         UINT_32 v = 0;
3326 
3327         if (pSwizzlePattern[i].x != 0)
3328         {
3329             UINT_16 mask  = pSwizzlePattern[i].x;
3330             UINT_32 xBits = x;
3331 
3332             while (mask != 0)
3333             {
3334                 if (mask & 1)
3335                 {
3336                     v ^= xBits & 1;
3337                 }
3338 
3339                 xBits >>= 1;
3340                 mask  >>= 1;
3341             }
3342         }
3343 
3344         if (pSwizzlePattern[i].y != 0)
3345         {
3346             UINT_16 mask  = pSwizzlePattern[i].y;
3347             UINT_32 yBits = y;
3348 
3349             while (mask != 0)
3350             {
3351                 if (mask & 1)
3352                 {
3353                     v ^= yBits & 1;
3354                 }
3355 
3356                 yBits >>= 1;
3357                 mask  >>= 1;
3358             }
3359         }
3360 
3361         if (pSwizzlePattern[i].z != 0)
3362         {
3363             UINT_16 mask  = pSwizzlePattern[i].z;
3364             UINT_32 zBits = z;
3365 
3366             while (mask != 0)
3367             {
3368                 if (mask & 1)
3369                 {
3370                     v ^= zBits & 1;
3371                 }
3372 
3373                 zBits >>= 1;
3374                 mask  >>= 1;
3375             }
3376         }
3377 
3378         if (pSwizzlePattern[i].s != 0)
3379         {
3380             UINT_16 mask  = pSwizzlePattern[i].s;
3381             UINT_32 sBits = s;
3382 
3383             while (mask != 0)
3384             {
3385                 if (mask & 1)
3386                 {
3387                     v ^= sBits & 1;
3388                 }
3389 
3390                 sBits >>= 1;
3391                 mask  >>= 1;
3392             }
3393         }
3394 
3395         offset |= (v << i);
3396     }
3397 
3398     return offset;
3399 }
3400 
3401 /**
3402 ************************************************************************************************************************
3403 *   Gfx11Lib::GetSwizzlePatternInfo
3404 *
3405 *   @brief
3406 *       Get swizzle pattern
3407 *
3408 *   @return
3409 *       Swizzle pattern information
3410 ************************************************************************************************************************
3411 */
GetSwizzlePatternInfo(AddrSwizzleMode swizzleMode,AddrResourceType resourceType,UINT_32 elemLog2,UINT_32 numFrag) const3412 const ADDR_SW_PATINFO* Gfx11Lib::GetSwizzlePatternInfo(
3413     AddrSwizzleMode  swizzleMode,       ///< Swizzle mode
3414     AddrResourceType resourceType,      ///< Resource type
3415     UINT_32          elemLog2,          ///< Element size in bytes log2
3416     UINT_32          numFrag            ///< Number of fragment
3417     ) const
3418 {
3419     const UINT_32          index       = IsXor(swizzleMode) ? (m_colorBaseIndex + elemLog2) : elemLog2;
3420     const ADDR_SW_PATINFO* patInfo     = NULL;
3421     const UINT_32          swizzleMask = 1 << swizzleMode;
3422     const BOOL_32          isBlock256k = IsBlock256kb(swizzleMode);
3423     const BOOL_32          isBlock64K  = IsBlock64kb(swizzleMode);
3424 
3425     if (IsLinear(swizzleMode) == FALSE)
3426     {
3427         if (resourceType == ADDR_RSRC_TEX_3D)
3428         {
3429             ADDR_ASSERT(numFrag == 1);
3430 
3431             if ((swizzleMask & Gfx11Rsrc3dSwModeMask) != 0)
3432             {
3433                 if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))
3434                 {
3435                     if (isBlock256k)
3436                     {
3437                         ADDR_ASSERT((swizzleMode == ADDR_SW_256KB_Z_X) || (swizzleMode == ADDR_SW_256KB_R_X));
3438                         patInfo = GFX11_SW_256K_ZR_X_1xaa_PATINFO;
3439                     }
3440                     else if (isBlock64K)
3441                     {
3442                         ADDR_ASSERT((swizzleMode == ADDR_SW_64KB_Z_X) || (swizzleMode == ADDR_SW_64KB_R_X));
3443                         patInfo = GFX11_SW_64K_ZR_X_1xaa_PATINFO;
3444                     }
3445                     else
3446                     {
3447                         ADDR_ASSERT_ALWAYS();
3448                     }
3449                 }
3450                 else if (IsDisplaySwizzle(resourceType, swizzleMode))
3451                 {
3452                     if (isBlock256k)
3453                     {
3454                         ADDR_ASSERT(swizzleMode == ADDR_SW_256KB_D_X);
3455                         // patInfo = GFX11_SW_256K_D3_X_PATINFO;
3456                     }
3457                     else if (isBlock64K)
3458                     {
3459                         ADDR_ASSERT(swizzleMode == ADDR_SW_64KB_D_X);
3460                         patInfo = GFX11_SW_64K_D3_X_PATINFO;
3461                     }
3462                     else
3463                     {
3464                         ADDR_ASSERT_ALWAYS();
3465                     }
3466                 }
3467                 else
3468                 {
3469                     ADDR_ASSERT(IsStandardSwizzle(resourceType, swizzleMode));
3470 
3471                     if (isBlock256k)
3472                     {
3473                         ADDR_ASSERT(swizzleMode == ADDR_SW_256KB_S_X);
3474                         patInfo = GFX11_SW_256K_S3_X_PATINFO;
3475                     }
3476                     else if (isBlock64K)
3477                     {
3478                         if (swizzleMode == ADDR_SW_64KB_S)
3479                         {
3480                             patInfo = GFX11_SW_64K_S3_PATINFO;
3481                         }
3482                         else if (swizzleMode == ADDR_SW_64KB_S_X)
3483                         {
3484                             patInfo = GFX11_SW_64K_S3_X_PATINFO;
3485                         }
3486                         else if (swizzleMode == ADDR_SW_64KB_S_T)
3487                         {
3488                             patInfo = GFX11_SW_64K_S3_T_PATINFO;
3489                         }
3490                         else
3491                         {
3492                             ADDR_ASSERT_ALWAYS();
3493                         }
3494                     }
3495                     else if (IsBlock4kb(swizzleMode))
3496                     {
3497                         if (swizzleMode == ADDR_SW_4KB_S)
3498                         {
3499                             patInfo = GFX11_SW_4K_S3_PATINFO;
3500                         }
3501                         else if (swizzleMode == ADDR_SW_4KB_S_X)
3502                         {
3503                             patInfo = GFX11_SW_4K_S3_X_PATINFO;
3504                         }
3505                         else
3506                         {
3507                             ADDR_ASSERT_ALWAYS();
3508                         }
3509                     }
3510                     else
3511                     {
3512                         ADDR_ASSERT_ALWAYS();
3513                     }
3514                 }
3515             }
3516         }
3517         else
3518         {
3519             if ((swizzleMask & Gfx11Rsrc2dSwModeMask) != 0)
3520             {
3521                 if (IsBlock256b(swizzleMode))
3522                 {
3523                     ADDR_ASSERT(swizzleMode == ADDR_SW_256B_D);
3524                     patInfo = GFX11_SW_256_D_PATINFO;
3525                 }
3526                 else if (IsBlock4kb(swizzleMode))
3527                 {
3528                     if (swizzleMode == ADDR_SW_4KB_D)
3529                     {
3530                         patInfo = GFX11_SW_4K_D_PATINFO;
3531                     }
3532                     else if (swizzleMode == ADDR_SW_4KB_D_X)
3533                     {
3534                         patInfo = GFX11_SW_4K_D_X_PATINFO;
3535                     }
3536                     else
3537                     {
3538                         ADDR_ASSERT_ALWAYS();
3539                     }
3540                 }
3541                 else if (isBlock64K)
3542                 {
3543                     if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))
3544                     {
3545                         if (numFrag == 1)
3546                         {
3547                             patInfo = GFX11_SW_64K_ZR_X_1xaa_PATINFO;
3548                         }
3549                         else if (numFrag == 2)
3550                         {
3551                             patInfo = GFX11_SW_64K_ZR_X_2xaa_PATINFO;
3552                         }
3553                         else if (numFrag == 4)
3554                         {
3555                             patInfo = GFX11_SW_64K_ZR_X_4xaa_PATINFO;
3556                         }
3557                         else if (numFrag == 8)
3558                         {
3559                             patInfo = GFX11_SW_64K_ZR_X_8xaa_PATINFO;
3560                         }
3561                         else
3562                         {
3563                             ADDR_ASSERT_ALWAYS();
3564                         }
3565                     }
3566                     else if (IsDisplaySwizzle(resourceType, swizzleMode))
3567                     {
3568                         if (swizzleMode == ADDR_SW_64KB_D)
3569                         {
3570                             patInfo = GFX11_SW_64K_D_PATINFO;
3571                         }
3572                         else if (swizzleMode == ADDR_SW_64KB_D_X)
3573                         {
3574                             patInfo = GFX11_SW_64K_D_X_PATINFO;
3575                         }
3576                         else if (swizzleMode == ADDR_SW_64KB_D_T)
3577                         {
3578                             patInfo = GFX11_SW_64K_D_T_PATINFO;
3579                         }
3580                         else
3581                         {
3582                             ADDR_ASSERT_ALWAYS();
3583                         }
3584                     }
3585                     else
3586                     {
3587                         ADDR_ASSERT_ALWAYS();
3588                     }
3589                 }
3590                 else if (isBlock256k)
3591                 {
3592                     if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))
3593                     {
3594                         if (numFrag == 1)
3595                         {
3596                             patInfo = GFX11_SW_256K_ZR_X_1xaa_PATINFO;
3597                         }
3598                         else if (numFrag == 2)
3599                         {
3600                             patInfo = GFX11_SW_256K_ZR_X_2xaa_PATINFO;
3601                         }
3602                         else if (numFrag == 4)
3603                         {
3604                             patInfo = GFX11_SW_256K_ZR_X_4xaa_PATINFO;
3605                         }
3606                         else if (numFrag == 8)
3607                         {
3608                             patInfo = GFX11_SW_256K_ZR_X_8xaa_PATINFO;
3609                         }
3610                         else
3611                         {
3612                             ADDR_ASSERT_ALWAYS();
3613                         }
3614                     }
3615                     else if (IsDisplaySwizzle(resourceType, swizzleMode))
3616                     {
3617                         ADDR_ASSERT(swizzleMode == ADDR_SW_256KB_D_X);
3618                         patInfo = GFX11_SW_256K_D_X_PATINFO;
3619                     }
3620                     else
3621                     {
3622                         ADDR_ASSERT_ALWAYS();
3623                     }
3624                 }
3625                 else
3626                 {
3627                     ADDR_ASSERT_ALWAYS();
3628                 }
3629             }
3630         }
3631     }
3632 
3633     return (patInfo != NULL) ? &patInfo[index] : NULL;
3634 }
3635 
3636 /**
3637 ************************************************************************************************************************
3638 *   Gfx11Lib::ComputeSurfaceAddrFromCoordMicroTiled
3639 *
3640 *   @brief
3641 *       Internal function to calculate address from coord for micro tiled swizzle surface
3642 *
3643 *   @return
3644 *       ADDR_E_RETURNCODE
3645 ************************************************************************************************************************
3646 */
ComputeSurfaceAddrFromCoordMicroTiled(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const3647 ADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceAddrFromCoordMicroTiled(
3648      const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
3649      ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
3650      ) const
3651 {
3652     ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {};
3653     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};
3654     ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];
3655 
3656     localIn.swizzleMode  = pIn->swizzleMode;
3657     localIn.flags        = pIn->flags;
3658     localIn.resourceType = pIn->resourceType;
3659     localIn.bpp          = pIn->bpp;
3660     localIn.width        = Max(pIn->unalignedWidth,  1u);
3661     localIn.height       = Max(pIn->unalignedHeight, 1u);
3662     localIn.numSlices    = Max(pIn->numSlices,       1u);
3663     localIn.numMipLevels = Max(pIn->numMipLevels,    1u);
3664     localIn.numSamples   = Max(pIn->numSamples,      1u);
3665     localIn.numFrags     = localIn.numSamples;
3666     localOut.pMipInfo    = mipInfo;
3667 
3668     ADDR_E_RETURNCODE ret = ComputeSurfaceInfoMicroTiled(&localIn, &localOut);
3669 
3670     if (ret == ADDR_OK)
3671     {
3672         const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);
3673         const UINT_32 rsrcType = static_cast<UINT_32>(pIn->resourceType) - 1;
3674         const UINT_32 swMode   = static_cast<UINT_32>(pIn->swizzleMode);
3675         const UINT_32 eqIndex  = m_equationLookupTable[rsrcType][swMode][elemLog2];
3676 
3677         if (eqIndex != ADDR_INVALID_EQUATION_INDEX)
3678         {
3679             const UINT_32 pb           = mipInfo[pIn->mipId].pitch / localOut.blockWidth;
3680             const UINT_32 yb           = pIn->y / localOut.blockHeight;
3681             const UINT_32 xb           = pIn->x / localOut.blockWidth;
3682             const UINT_32 blockIndex   = yb * pb + xb;
3683             const UINT_32 blockSize    = 256;
3684             const UINT_32 blk256Offset = ComputeOffsetFromEquation(&m_equationTable[eqIndex],
3685                                                                    pIn->x << elemLog2,
3686                                                                    pIn->y,
3687                                                                    0);
3688             pOut->addr = localOut.sliceSize * pIn->slice +
3689                          mipInfo[pIn->mipId].macroBlockOffset +
3690                          (blockIndex * blockSize) +
3691                          blk256Offset;
3692         }
3693         else
3694         {
3695             ret = ADDR_INVALIDPARAMS;
3696         }
3697     }
3698 
3699     return ret;
3700 }
3701 
3702 /**
3703 ************************************************************************************************************************
3704 *   Gfx11Lib::ComputeSurfaceAddrFromCoordMacroTiled
3705 *
3706 *   @brief
3707 *       Internal function to calculate address from coord for macro tiled swizzle surface
3708 *
3709 *   @return
3710 *       ADDR_E_RETURNCODE
3711 ************************************************************************************************************************
3712 */
ComputeSurfaceAddrFromCoordMacroTiled(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const3713 ADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceAddrFromCoordMacroTiled(
3714      const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn,    ///< [in] input structure
3715      ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT*      pOut    ///< [out] output structure
3716      ) const
3717 {
3718     ADDR2_COMPUTE_SURFACE_INFO_INPUT  localIn  = {};
3719     ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};
3720     ADDR2_MIP_INFO                    mipInfo[MaxMipLevels];
3721 
3722     localIn.swizzleMode  = pIn->swizzleMode;
3723     localIn.flags        = pIn->flags;
3724     localIn.resourceType = pIn->resourceType;
3725     localIn.bpp          = pIn->bpp;
3726     localIn.width        = Max(pIn->unalignedWidth,  1u);
3727     localIn.height       = Max(pIn->unalignedHeight, 1u);
3728     localIn.numSlices    = Max(pIn->numSlices,       1u);
3729     localIn.numMipLevels = Max(pIn->numMipLevels,    1u);
3730     localIn.numSamples   = Max(pIn->numSamples,      1u);
3731     localIn.numFrags     = localIn.numSamples;
3732     localOut.pMipInfo    = mipInfo;
3733 
3734     ADDR_E_RETURNCODE ret = ComputeSurfaceInfoMacroTiled(&localIn, &localOut);
3735 
3736     if (ret == ADDR_OK)
3737     {
3738         const UINT_32 elemLog2    = Log2(pIn->bpp >> 3);
3739         const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);
3740         const UINT_32 blkMask     = (1 << blkSizeLog2) - 1;
3741         const UINT_32 pipeMask    = (1 << m_pipesLog2) - 1;
3742         const UINT_32 bankMask    = ((1 << GetBankXorBits(blkSizeLog2)) - 1) << (m_pipesLog2 + ColumnBits);
3743         const UINT_32 pipeBankXor = IsXor(pIn->swizzleMode) ?
3744                                     (((pIn->pipeBankXor & (pipeMask | bankMask)) << m_pipeInterleaveLog2) & blkMask) : 0;
3745 
3746         if (localIn.numSamples > 1)
3747         {
3748             const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(pIn->swizzleMode,
3749                                                                     pIn->resourceType,
3750                                                                     elemLog2,
3751                                                                     localIn.numSamples);
3752 
3753             if (pPatInfo != NULL)
3754             {
3755                 const UINT_32 pb     = localOut.pitch / localOut.blockWidth;
3756                 const UINT_32 yb     = pIn->y / localOut.blockHeight;
3757                 const UINT_32 xb     = pIn->x / localOut.blockWidth;
3758                 const UINT_64 blkIdx = yb * pb + xb;
3759 
3760                 ADDR_BIT_SETTING fullSwizzlePattern[20];
3761                 GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);
3762 
3763                 const UINT_32 blkOffset =
3764                     ComputeOffsetFromSwizzlePattern(reinterpret_cast<const UINT_64*>(fullSwizzlePattern),
3765                                                     blkSizeLog2,
3766                                                     pIn->x,
3767                                                     pIn->y,
3768                                                     pIn->slice,
3769                                                     pIn->sample);
3770 
3771                 pOut->addr = (localOut.sliceSize * pIn->slice) +
3772                              (blkIdx << blkSizeLog2) +
3773                              (blkOffset ^ pipeBankXor);
3774             }
3775             else
3776             {
3777                 ret = ADDR_INVALIDPARAMS;
3778             }
3779         }
3780         else
3781         {
3782             const UINT_32 rsrcIdx = (pIn->resourceType == ADDR_RSRC_TEX_3D) ? 1 : 0;
3783             const UINT_32 swMode  = static_cast<UINT_32>(pIn->swizzleMode);
3784             const UINT_32 eqIndex = m_equationLookupTable[rsrcIdx][swMode][elemLog2];
3785 
3786             if (eqIndex != ADDR_INVALID_EQUATION_INDEX)
3787             {
3788                 const BOOL_32 inTail    = (mipInfo[pIn->mipId].mipTailOffset != 0) ? TRUE : FALSE;
3789                 const BOOL_32 isThin    = IsThin(pIn->resourceType, pIn->swizzleMode);
3790                 const UINT_64 sliceSize = isThin ? localOut.sliceSize : (localOut.sliceSize * localOut.blockSlices);
3791                 const UINT_32 sliceId   = isThin ? pIn->slice : (pIn->slice / localOut.blockSlices);
3792                 const UINT_32 x         = inTail ? (pIn->x     + mipInfo[pIn->mipId].mipTailCoordX) : pIn->x;
3793                 const UINT_32 y         = inTail ? (pIn->y     + mipInfo[pIn->mipId].mipTailCoordY) : pIn->y;
3794                 const UINT_32 z         = inTail ? (pIn->slice + mipInfo[pIn->mipId].mipTailCoordZ) : pIn->slice;
3795                 const UINT_32 pb        = mipInfo[pIn->mipId].pitch / localOut.blockWidth;
3796                 const UINT_32 yb        = pIn->y / localOut.blockHeight;
3797                 const UINT_32 xb        = pIn->x / localOut.blockWidth;
3798                 const UINT_64 blkIdx    = yb * pb + xb;
3799                 const UINT_32 blkOffset = ComputeOffsetFromEquation(&m_equationTable[eqIndex],
3800                                                                     x << elemLog2,
3801                                                                     y,
3802                                                                     z);
3803                 pOut->addr = sliceSize * sliceId +
3804                              mipInfo[pIn->mipId].macroBlockOffset +
3805                              (blkIdx << blkSizeLog2) +
3806                              (blkOffset ^ pipeBankXor);
3807             }
3808             else
3809             {
3810                 ret = ADDR_INVALIDPARAMS;
3811             }
3812         }
3813     }
3814 
3815     return ret;
3816 }
3817 
3818 /**
3819 ************************************************************************************************************************
3820 *   Gfx11Lib::HwlComputeMaxBaseAlignments
3821 *
3822 *   @brief
3823 *       Gets maximum alignments
3824 *   @return
3825 *       maximum alignments
3826 ************************************************************************************************************************
3827 */
HwlComputeMaxBaseAlignments() const3828 UINT_32 Gfx11Lib::HwlComputeMaxBaseAlignments() const
3829 {
3830     return Size256K;
3831 }
3832 
3833 /**
3834 ************************************************************************************************************************
3835 *   Gfx11Lib::HwlComputeMaxMetaBaseAlignments
3836 *
3837 *   @brief
3838 *       Gets maximum alignments for metadata
3839 *   @return
3840 *       maximum alignments for metadata
3841 ************************************************************************************************************************
3842 */
HwlComputeMaxMetaBaseAlignments() const3843 UINT_32 Gfx11Lib::HwlComputeMaxMetaBaseAlignments() const
3844 {
3845     Dim3d metaBlk;
3846 
3847     // Max base alignment for Htile
3848     const AddrSwizzleMode ValidSwizzleModeForHtile[] =
3849     {
3850         ADDR_SW_64KB_Z_X,
3851         ADDR_SW_256KB_Z_X,
3852     };
3853 
3854     UINT_32 maxBaseAlignHtile = 0;
3855 
3856     for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForHtile) / sizeof(ValidSwizzleModeForHtile[0]); swIdx++)
3857     {
3858         for (UINT_32 bppLog2 = 0; bppLog2 < 3; bppLog2++)
3859         {
3860             for (UINT_32 numFragLog2 = 0; numFragLog2 < 4; numFragLog2++)
3861             {
3862                 const UINT_32 metaBlkSizeHtile = GetMetaBlkSize(Gfx11DataDepthStencil,
3863                                                                 ADDR_RSRC_TEX_2D,
3864                                                                 ValidSwizzleModeForHtile[swIdx],
3865                                                                 bppLog2,
3866                                                                 numFragLog2,
3867                                                                 TRUE,
3868                                                                 &metaBlk);
3869 
3870                 maxBaseAlignHtile = Max(maxBaseAlignHtile, metaBlkSizeHtile);
3871             }
3872         }
3873     }
3874 
3875     // Max base alignment for 2D Dcc
3876     // swizzle mode support DCC...
3877     const AddrSwizzleMode ValidSwizzleModeForDcc2D[] =
3878     {
3879         ADDR_SW_64KB_R_X,
3880         ADDR_SW_256KB_R_X,
3881     };
3882 
3883     UINT_32 maxBaseAlignDcc2D = 0;
3884 
3885     for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForDcc2D) / sizeof(ValidSwizzleModeForDcc2D[0]); swIdx++)
3886     {
3887         for (UINT_32 bppLog2 = 0; bppLog2 < MaxNumOfBpp; bppLog2++)
3888         {
3889             for (UINT_32 numFragLog2 = 0; numFragLog2 < 4; numFragLog2++)
3890             {
3891                 const UINT_32 metaBlkSize2D = GetMetaBlkSize(Gfx11DataColor,
3892                                                              ADDR_RSRC_TEX_2D,
3893                                                              ValidSwizzleModeForDcc2D[swIdx],
3894                                                              bppLog2,
3895                                                              numFragLog2,
3896                                                              TRUE,
3897                                                              &metaBlk);
3898 
3899                 maxBaseAlignDcc2D = Max(maxBaseAlignDcc2D, metaBlkSize2D);
3900             }
3901         }
3902     }
3903 
3904     // Max base alignment for 3D Dcc
3905     const AddrSwizzleMode ValidSwizzleModeForDcc3D[] =
3906     {
3907         ADDR_SW_64KB_S_X,
3908         ADDR_SW_64KB_D_X,
3909         ADDR_SW_64KB_R_X,
3910         ADDR_SW_256KB_S_X,
3911         ADDR_SW_256KB_D_X,
3912         ADDR_SW_256KB_R_X,
3913     };
3914 
3915     UINT_32 maxBaseAlignDcc3D = 0;
3916 
3917     for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForDcc3D) / sizeof(ValidSwizzleModeForDcc3D[0]); swIdx++)
3918     {
3919         for (UINT_32 bppLog2 = 0; bppLog2 < MaxNumOfBpp; bppLog2++)
3920         {
3921             const UINT_32 metaBlkSize3D = GetMetaBlkSize(Gfx11DataColor,
3922                                                          ADDR_RSRC_TEX_3D,
3923                                                          ValidSwizzleModeForDcc3D[swIdx],
3924                                                          bppLog2,
3925                                                          0,
3926                                                          TRUE,
3927                                                          &metaBlk);
3928 
3929             maxBaseAlignDcc3D = Max(maxBaseAlignDcc3D, metaBlkSize3D);
3930         }
3931     }
3932 
3933     return Max(maxBaseAlignHtile, Max(maxBaseAlignDcc2D, maxBaseAlignDcc3D));
3934 }
3935 
3936 /**
3937 ************************************************************************************************************************
3938 *   Gfx11Lib::GetMetaElementSizeLog2
3939 *
3940 *   @brief
3941 *       Gets meta data element size log2
3942 *   @return
3943 *       Meta data element size log2
3944 ************************************************************************************************************************
3945 */
GetMetaElementSizeLog2(Gfx11DataType dataType)3946 INT_32 Gfx11Lib::GetMetaElementSizeLog2(
3947     Gfx11DataType dataType) ///< Data surface type
3948 {
3949     INT_32 elemSizeLog2 = 0;
3950 
3951     if (dataType == Gfx11DataColor)
3952     {
3953         elemSizeLog2 = 0;
3954     }
3955     else
3956     {
3957         ADDR_ASSERT(dataType == Gfx11DataDepthStencil);
3958         elemSizeLog2 = 2;
3959     }
3960 
3961     return elemSizeLog2;
3962 }
3963 
3964 /**
3965 ************************************************************************************************************************
3966 *   Gfx11Lib::GetMetaCacheSizeLog2
3967 *
3968 *   @brief
3969 *       Gets meta data cache line size log2
3970 *   @return
3971 *       Meta data cache line size log2
3972 ************************************************************************************************************************
3973 */
GetMetaCacheSizeLog2(Gfx11DataType dataType)3974 INT_32 Gfx11Lib::GetMetaCacheSizeLog2(
3975     Gfx11DataType dataType) ///< Data surface type
3976 {
3977     INT_32 cacheSizeLog2 = 0;
3978 
3979     if (dataType == Gfx11DataColor)
3980     {
3981         cacheSizeLog2 = 6;
3982     }
3983     else
3984     {
3985         ADDR_ASSERT(dataType == Gfx11DataDepthStencil);
3986         cacheSizeLog2 = 8;
3987     }
3988 
3989     return cacheSizeLog2;
3990 }
3991 
3992 /**
3993 ************************************************************************************************************************
3994 *   Gfx11Lib::HwlComputeSurfaceInfoLinear
3995 *
3996 *   @brief
3997 *       Internal function to calculate alignment for linear surface
3998 *
3999 *   @return
4000 *       ADDR_E_RETURNCODE
4001 ************************************************************************************************************************
4002 */
HwlComputeSurfaceInfoLinear(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const4003 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceInfoLinear(
4004      const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn,    ///< [in] input structure
4005      ADDR2_COMPUTE_SURFACE_INFO_OUTPUT*      pOut    ///< [out] output structure
4006      ) const
4007 {
4008     ADDR_E_RETURNCODE returnCode = ADDR_OK;
4009 
4010     if (IsTex1d(pIn->resourceType) && (pIn->height > 1))
4011     {
4012         returnCode = ADDR_INVALIDPARAMS;
4013     }
4014     else
4015     {
4016         const UINT_32 elementBytes = pIn->bpp >> 3;
4017         const UINT_32 pitchAlign   = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? 1 : (256 / elementBytes);
4018         const UINT_32 mipDepth     = (pIn->resourceType == ADDR_RSRC_TEX_3D) ? pIn->numSlices : 1;
4019         UINT_32       pitch        = PowTwoAlign(pIn->width, pitchAlign);
4020         UINT_32       actualHeight = pIn->height;
4021         UINT_64       sliceSize    = 0;
4022 
4023         if (pIn->numMipLevels > 1)
4024         {
4025             for (INT_32 i = static_cast<INT_32>(pIn->numMipLevels) - 1; i >= 0; i--)
4026             {
4027                 UINT_32 mipWidth, mipHeight;
4028 
4029                 GetMipSize(pIn->width, pIn->height, 1, i, &mipWidth, &mipHeight);
4030 
4031                 const UINT_32 mipActualWidth = PowTwoAlign(mipWidth, pitchAlign);
4032 
4033                 if (pOut->pMipInfo != NULL)
4034                 {
4035                     pOut->pMipInfo[i].pitch            = mipActualWidth;
4036                     pOut->pMipInfo[i].height           = mipHeight;
4037                     pOut->pMipInfo[i].depth            = mipDepth;
4038                     pOut->pMipInfo[i].offset           = sliceSize;
4039                     pOut->pMipInfo[i].mipTailOffset    = 0;
4040                     pOut->pMipInfo[i].macroBlockOffset = sliceSize;
4041                 }
4042 
4043                 sliceSize += static_cast<UINT_64>(mipActualWidth) * mipHeight * elementBytes;
4044             }
4045         }
4046         else
4047         {
4048             returnCode = ApplyCustomizedPitchHeight(pIn, elementBytes, pitchAlign, &pitch, &actualHeight);
4049 
4050             if (returnCode == ADDR_OK)
4051             {
4052                 sliceSize = static_cast<UINT_64>(pitch) * actualHeight * elementBytes;
4053 
4054                 if (pOut->pMipInfo != NULL)
4055                 {
4056                     pOut->pMipInfo[0].pitch            = pitch;
4057                     pOut->pMipInfo[0].height           = actualHeight;
4058                     pOut->pMipInfo[0].depth            = mipDepth;
4059                     pOut->pMipInfo[0].offset           = 0;
4060                     pOut->pMipInfo[0].mipTailOffset    = 0;
4061                     pOut->pMipInfo[0].macroBlockOffset = 0;
4062                 }
4063             }
4064         }
4065 
4066         if (returnCode == ADDR_OK)
4067         {
4068             pOut->pitch          = pitch;
4069             pOut->height         = actualHeight;
4070             pOut->numSlices      = pIn->numSlices;
4071             pOut->sliceSize      = sliceSize;
4072             pOut->surfSize       = sliceSize * pOut->numSlices;
4073             pOut->baseAlign      = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? elementBytes : 256;
4074             pOut->blockWidth     = pitchAlign;
4075             pOut->blockHeight    = 1;
4076             pOut->blockSlices    = 1;
4077 
4078             // Following members are useless on GFX11
4079             pOut->mipChainPitch  = 0;
4080             pOut->mipChainHeight = 0;
4081             pOut->mipChainSlice  = 0;
4082             pOut->epitchIsHeight = FALSE;
4083 
4084             // Post calculation validate
4085             ADDR_ASSERT(pOut->sliceSize > 0);
4086         }
4087     }
4088 
4089     return returnCode;
4090 }
4091 
4092 } // V2
4093 } // Addr
4094