2 * Copyright © 2017 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 ****************************************************************************************************
29 * @file gfx9addrlib.cpp
30 * @brief Contgfx9ns the implementation for the Gfx9Lib class.
31 ****************************************************************************************************
34 #include "gfx9addrlib.h"
36 #include "gfx9_gb_reg.h"
37 #include "gfx9_enum.h"
40 #include "amdgpu_id.h"
46 ////////////////////////////////////////////////////////////////////////////////////////////////////
47 ////////////////////////////////////////////////////////////////////////////////////////////////////
53 ****************************************************************************************************
57 * Creates an Gfx9Lib object.
60 * Returns an Gfx9Lib object pointer.
61 ****************************************************************************************************
63 Addr::Lib
* Gfx9HwlInit(const Client
* pClient
)
65 return V2::Gfx9Lib::CreateObj(pClient
);
72 ****************************************************************************************************
78 ****************************************************************************************************
80 Gfx9Lib::Gfx9Lib(const Client
* pClient
)
86 memset(&m_settings
, 0, sizeof(m_settings
));
90 ****************************************************************************************************
95 ****************************************************************************************************
102 ****************************************************************************************************
103 * Gfx9Lib::HwlComputeHtileInfo
106 * Interface function stub of AddrComputeHtilenfo
110 ****************************************************************************************************
112 ADDR_E_RETURNCODE
Gfx9Lib::HwlComputeHtileInfo(
113 const ADDR2_COMPUTE_HTILE_INFO_INPUT
* pIn
, ///< [in] input structure
114 ADDR2_COMPUTE_HTILE_INFO_OUTPUT
* pOut
///< [out] output structure
117 UINT_32 numPipeTotal
= GetPipeNumForMetaAddressing(pIn
->hTileFlags
.pipeAligned
,
120 UINT_32 numRbTotal
= pIn
->hTileFlags
.rbAligned
? m_se
* m_rbPerSe
: 1;
122 UINT_32 numCompressBlkPerMetaBlk
, numCompressBlkPerMetaBlkLog2
;
124 if ((numPipeTotal
== 1) && (numRbTotal
== 1))
126 numCompressBlkPerMetaBlkLog2
= 10;
130 numCompressBlkPerMetaBlkLog2
= m_seLog2
+ m_rbPerSeLog2
+ 10;
133 numCompressBlkPerMetaBlk
= 1 << numCompressBlkPerMetaBlkLog2
;
135 Dim3d metaBlkDim
= {8, 8, 1};
136 UINT_32 totalAmpBits
= numCompressBlkPerMetaBlkLog2
;
137 UINT_32 widthAmp
= (pIn
->numMipLevels
> 1) ? (totalAmpBits
>> 1) : RoundHalf(totalAmpBits
);
138 UINT_32 heightAmp
= totalAmpBits
- widthAmp
;
139 metaBlkDim
.w
<<= widthAmp
;
140 metaBlkDim
.h
<<= heightAmp
;
143 Dim3d metaBlkDimDbg
= {8, 8, 1};
144 for (UINT_32 index
= 0; index
< numCompressBlkPerMetaBlkLog2
; index
++)
146 if ((metaBlkDimDbg
.h
< metaBlkDimDbg
.w
) ||
147 ((pIn
->numMipLevels
> 1) && (metaBlkDimDbg
.h
== metaBlkDimDbg
.w
)))
149 metaBlkDimDbg
.h
<<= 1;
153 metaBlkDimDbg
.w
<<= 1;
156 ADDR_ASSERT((metaBlkDimDbg
.w
== metaBlkDim
.w
) && (metaBlkDimDbg
.h
== metaBlkDim
.h
));
163 GetMetaMipInfo(pIn
->numMipLevels
, &metaBlkDim
, FALSE
, pOut
->pMipInfo
,
164 pIn
->unalignedWidth
, pIn
->unalignedHeight
, pIn
->numSlices
,
165 &numMetaBlkX
, &numMetaBlkY
, &numMetaBlkZ
);
167 UINT_32 sizeAlign
= numPipeTotal
* numRbTotal
* m_pipeInterleaveBytes
;
169 pOut
->pitch
= numMetaBlkX
* metaBlkDim
.w
;
170 pOut
->height
= numMetaBlkY
* metaBlkDim
.h
;
171 pOut
->sliceSize
= numMetaBlkX
* numMetaBlkY
* numCompressBlkPerMetaBlk
* 4;
173 pOut
->metaBlkWidth
= metaBlkDim
.w
;
174 pOut
->metaBlkHeight
= metaBlkDim
.h
;
175 pOut
->metaBlkNumPerSlice
= numMetaBlkX
* numMetaBlkY
;
177 if ((IsXor(pIn
->swizzleMode
) == FALSE
) && (numPipeTotal
> 2))
179 UINT_32 additionalAlign
= numPipeTotal
* numCompressBlkPerMetaBlk
* 2;
181 if (additionalAlign
> sizeAlign
)
183 sizeAlign
= additionalAlign
;
187 pOut
->htileBytes
= PowTwoAlign(pOut
->sliceSize
* numMetaBlkZ
, sizeAlign
);
188 pOut
->baseAlign
= Max(numCompressBlkPerMetaBlk
* 4, sizeAlign
);
190 if (m_settings
.metaBaseAlignFix
)
192 pOut
->baseAlign
= Max(pOut
->baseAlign
, HwlComputeSurfaceBaseAlign(pIn
->swizzleMode
));
199 ****************************************************************************************************
200 * Gfx9Lib::HwlComputeCmaskInfo
203 * Interface function stub of AddrComputeCmaskInfo
207 ****************************************************************************************************
209 ADDR_E_RETURNCODE
Gfx9Lib::HwlComputeCmaskInfo(
210 const ADDR2_COMPUTE_CMASK_INFO_INPUT
* pIn
, ///< [in] input structure
211 ADDR2_COMPUTE_CMASK_INFO_OUTPUT
* pOut
///< [out] output structure
214 ADDR_ASSERT(pIn
->resourceType
== ADDR_RSRC_TEX_2D
);
216 UINT_32 numPipeTotal
= GetPipeNumForMetaAddressing(pIn
->cMaskFlags
.pipeAligned
,
219 UINT_32 numRbTotal
= pIn
->cMaskFlags
.rbAligned
? m_se
* m_rbPerSe
: 1;
221 UINT_32 numCompressBlkPerMetaBlkLog2
, numCompressBlkPerMetaBlk
;
223 if ((numPipeTotal
== 1) && (numRbTotal
== 1))
225 numCompressBlkPerMetaBlkLog2
= 13;
229 numCompressBlkPerMetaBlkLog2
= m_seLog2
+ m_rbPerSeLog2
+ 10;
231 numCompressBlkPerMetaBlkLog2
= Max(numCompressBlkPerMetaBlkLog2
, 13u);
234 numCompressBlkPerMetaBlk
= 1 << numCompressBlkPerMetaBlkLog2
;
236 Dim2d metaBlkDim
= {8, 8};
237 UINT_32 totalAmpBits
= numCompressBlkPerMetaBlkLog2
;
238 UINT_32 heightAmp
= totalAmpBits
>> 1;
239 UINT_32 widthAmp
= totalAmpBits
- heightAmp
;
240 metaBlkDim
.w
<<= widthAmp
;
241 metaBlkDim
.h
<<= heightAmp
;
244 Dim2d metaBlkDimDbg
= {8, 8};
245 for (UINT_32 index
= 0; index
< numCompressBlkPerMetaBlkLog2
; index
++)
247 if (metaBlkDimDbg
.h
< metaBlkDimDbg
.w
)
249 metaBlkDimDbg
.h
<<= 1;
253 metaBlkDimDbg
.w
<<= 1;
256 ADDR_ASSERT((metaBlkDimDbg
.w
== metaBlkDim
.w
) && (metaBlkDimDbg
.h
== metaBlkDim
.h
));
259 UINT_32 numMetaBlkX
= (pIn
->unalignedWidth
+ metaBlkDim
.w
- 1) / metaBlkDim
.w
;
260 UINT_32 numMetaBlkY
= (pIn
->unalignedHeight
+ metaBlkDim
.h
- 1) / metaBlkDim
.h
;
261 UINT_32 numMetaBlkZ
= Max(pIn
->numSlices
, 1u);
263 UINT_32 sizeAlign
= numPipeTotal
* numRbTotal
* m_pipeInterleaveBytes
;
265 pOut
->pitch
= numMetaBlkX
* metaBlkDim
.w
;
266 pOut
->height
= numMetaBlkY
* metaBlkDim
.h
;
267 pOut
->sliceSize
= (numMetaBlkX
* numMetaBlkY
* numCompressBlkPerMetaBlk
) >> 1;
268 pOut
->cmaskBytes
= PowTwoAlign(pOut
->sliceSize
* numMetaBlkZ
, sizeAlign
);
269 pOut
->baseAlign
= Max(numCompressBlkPerMetaBlk
>> 1, sizeAlign
);
271 if (m_settings
.metaBaseAlignFix
)
273 pOut
->baseAlign
= Max(pOut
->baseAlign
, HwlComputeSurfaceBaseAlign(pIn
->swizzleMode
));
276 pOut
->metaBlkWidth
= metaBlkDim
.w
;
277 pOut
->metaBlkHeight
= metaBlkDim
.h
;
279 pOut
->metaBlkNumPerSlice
= numMetaBlkX
* numMetaBlkY
;
285 ****************************************************************************************************
286 * Gfx9Lib::GetMetaMipInfo
293 ****************************************************************************************************
295 VOID
Gfx9Lib::GetMetaMipInfo(
296 UINT_32 numMipLevels
, ///< [in] number of mip levels
297 Dim3d
* pMetaBlkDim
, ///< [in] meta block dimension
298 BOOL_32 dataThick
, ///< [in] data surface is thick
299 ADDR2_META_MIP_INFO
* pInfo
, ///< [out] meta mip info
300 UINT_32 mip0Width
, ///< [in] mip0 width
301 UINT_32 mip0Height
, ///< [in] mip0 height
302 UINT_32 mip0Depth
, ///< [in] mip0 depth
303 UINT_32
* pNumMetaBlkX
, ///< [out] number of metablock X in mipchain
304 UINT_32
* pNumMetaBlkY
, ///< [out] number of metablock Y in mipchain
305 UINT_32
* pNumMetaBlkZ
) ///< [out] number of metablock Z in mipchain
308 UINT_32 numMetaBlkX
= (mip0Width
+ pMetaBlkDim
->w
- 1) / pMetaBlkDim
->w
;
309 UINT_32 numMetaBlkY
= (mip0Height
+ pMetaBlkDim
->h
- 1) / pMetaBlkDim
->h
;
310 UINT_32 numMetaBlkZ
= (mip0Depth
+ pMetaBlkDim
->d
- 1) / pMetaBlkDim
->d
;
311 UINT_32 tailWidth
= pMetaBlkDim
->w
;
312 UINT_32 tailHeight
= pMetaBlkDim
->h
>> 1;
313 UINT_32 tailDepth
= pMetaBlkDim
->d
;
314 BOOL_32 inTail
= FALSE
;
315 AddrMajorMode major
= ADDR_MAJOR_MAX_TYPE
;
317 if (numMipLevels
> 1)
319 if (dataThick
&& (numMetaBlkZ
> numMetaBlkX
) && (numMetaBlkZ
> numMetaBlkY
))
322 major
= ADDR_MAJOR_Z
;
324 else if (numMetaBlkX
>= numMetaBlkY
)
327 major
= ADDR_MAJOR_X
;
332 major
= ADDR_MAJOR_Y
;
335 inTail
= ((mip0Width
<= tailWidth
) &&
336 (mip0Height
<= tailHeight
) &&
337 ((dataThick
== FALSE
) || (mip0Depth
<= tailDepth
)));
345 if (major
== ADDR_MAJOR_Z
)
348 pMipDim
= &numMetaBlkY
;
349 pOrderDim
= &numMetaBlkZ
;
352 else if (major
== ADDR_MAJOR_X
)
355 pMipDim
= &numMetaBlkY
;
356 pOrderDim
= &numMetaBlkX
;
362 pMipDim
= &numMetaBlkX
;
363 pOrderDim
= &numMetaBlkY
;
367 if ((*pMipDim
< 3) && (*pOrderDim
> orderLimit
) && (numMipLevels
> 3))
373 *pMipDim
+= ((*pMipDim
/ 2) + (*pMipDim
& 1));
380 UINT_32 mipWidth
= mip0Width
;
381 UINT_32 mipHeight
= mip0Height
;
382 UINT_32 mipDepth
= mip0Depth
;
383 Dim3d mipCoord
= {0};
385 for (UINT_32 mip
= 0; mip
< numMipLevels
; mip
++)
389 GetMetaMiptailInfo(&pInfo
[mip
], mipCoord
, numMipLevels
- mip
,
395 mipWidth
= PowTwoAlign(mipWidth
, pMetaBlkDim
->w
);
396 mipHeight
= PowTwoAlign(mipHeight
, pMetaBlkDim
->h
);
397 mipDepth
= PowTwoAlign(mipDepth
, pMetaBlkDim
->d
);
399 pInfo
[mip
].inMiptail
= FALSE
;
400 pInfo
[mip
].startX
= mipCoord
.w
;
401 pInfo
[mip
].startY
= mipCoord
.h
;
402 pInfo
[mip
].startZ
= mipCoord
.d
;
403 pInfo
[mip
].width
= mipWidth
;
404 pInfo
[mip
].height
= mipHeight
;
405 pInfo
[mip
].depth
= dataThick
? mipDepth
: 1;
407 if ((mip
>= 3) || (mip
& 1))
412 mipCoord
.w
+= mipWidth
;
415 mipCoord
.h
+= mipHeight
;
418 mipCoord
.d
+= mipDepth
;
429 mipCoord
.h
+= mipHeight
;
432 mipCoord
.w
+= mipWidth
;
435 mipCoord
.h
+= mipHeight
;
442 mipWidth
= Max(mipWidth
>> 1, 1u);
443 mipHeight
= Max(mipHeight
>> 1, 1u);
444 mipDepth
= Max(mipDepth
>> 1, 1u);
446 inTail
= ((mipWidth
<= tailWidth
) &&
447 (mipHeight
<= tailHeight
) &&
448 ((dataThick
== FALSE
) || (mipDepth
<= tailDepth
)));
453 *pNumMetaBlkX
= numMetaBlkX
;
454 *pNumMetaBlkY
= numMetaBlkY
;
455 *pNumMetaBlkZ
= numMetaBlkZ
;
459 ****************************************************************************************************
460 * Gfx9Lib::HwlComputeDccInfo
463 * Interface function to compute DCC key info
467 ****************************************************************************************************
469 ADDR_E_RETURNCODE
Gfx9Lib::HwlComputeDccInfo(
470 const ADDR2_COMPUTE_DCCINFO_INPUT
* pIn
, ///< [in] input structure
471 ADDR2_COMPUTE_DCCINFO_OUTPUT
* pOut
///< [out] output structure
474 BOOL_32 dataLinear
= IsLinear(pIn
->swizzleMode
);
475 BOOL_32 metaLinear
= pIn
->dccKeyFlags
.linear
;
476 BOOL_32 pipeAligned
= pIn
->dccKeyFlags
.pipeAligned
;
482 else if (metaLinear
== TRUE
)
487 UINT_32 numPipeTotal
= GetPipeNumForMetaAddressing(pipeAligned
, pIn
->swizzleMode
);
491 // Linear metadata supporting was removed for GFX9! No one can use this feature on GFX9.
492 ADDR_ASSERT_ALWAYS();
494 pOut
->dccRamBaseAlign
= numPipeTotal
* m_pipeInterleaveBytes
;
495 pOut
->dccRamSize
= PowTwoAlign((pIn
->dataSurfaceSize
/ 256), pOut
->dccRamBaseAlign
);
499 BOOL_32 dataThick
= IsThick(pIn
->resourceType
, pIn
->swizzleMode
);
501 UINT_32 minMetaBlkSize
= dataThick
? 65536 : 4096;
503 UINT_32 numFrags
= (pIn
->numFrags
== 0) ? 1 : pIn
->numFrags
;
504 UINT_32 numSlices
= (pIn
->numSlices
== 0) ? 1 : pIn
->numSlices
;
506 minMetaBlkSize
/= numFrags
;
508 UINT_32 numCompressBlkPerMetaBlk
= minMetaBlkSize
;
510 UINT_32 numRbTotal
= pIn
->dccKeyFlags
.rbAligned
? m_se
* m_rbPerSe
: 1;
512 if ((numPipeTotal
> 1) || (numRbTotal
> 1))
514 numCompressBlkPerMetaBlk
=
515 Max(numCompressBlkPerMetaBlk
, m_se
* m_rbPerSe
* (dataThick
? 262144 : 1024));
517 if (numCompressBlkPerMetaBlk
> 65536 * pIn
->bpp
)
519 numCompressBlkPerMetaBlk
= 65536 * pIn
->bpp
;
523 Dim3d compressBlkDim
= GetDccCompressBlk(pIn
->resourceType
, pIn
->swizzleMode
, pIn
->bpp
);
524 Dim3d metaBlkDim
= compressBlkDim
;
526 for (UINT_32 index
= 1; index
< numCompressBlkPerMetaBlk
; index
<<= 1)
528 if ((metaBlkDim
.h
< metaBlkDim
.w
) ||
529 ((pIn
->numMipLevels
> 1) && (metaBlkDim
.h
== metaBlkDim
.w
)))
531 if ((dataThick
== FALSE
) || (metaBlkDim
.h
<= metaBlkDim
.d
))
542 if ((dataThick
== FALSE
) || (metaBlkDim
.w
<= metaBlkDim
.d
))
557 GetMetaMipInfo(pIn
->numMipLevels
, &metaBlkDim
, dataThick
, pOut
->pMipInfo
,
558 pIn
->unalignedWidth
, pIn
->unalignedHeight
, numSlices
,
559 &numMetaBlkX
, &numMetaBlkY
, &numMetaBlkZ
);
561 UINT_32 sizeAlign
= numPipeTotal
* numRbTotal
* m_pipeInterleaveBytes
;
563 if (numFrags
> m_maxCompFrag
)
565 sizeAlign
*= (numFrags
/ m_maxCompFrag
);
568 pOut
->dccRamSize
= numMetaBlkX
* numMetaBlkY
* numMetaBlkZ
*
569 numCompressBlkPerMetaBlk
* numFrags
;
570 pOut
->dccRamSize
= PowTwoAlign(pOut
->dccRamSize
, sizeAlign
);
571 pOut
->dccRamBaseAlign
= Max(numCompressBlkPerMetaBlk
, sizeAlign
);
573 if (m_settings
.metaBaseAlignFix
)
575 pOut
->dccRamBaseAlign
= Max(pOut
->dccRamBaseAlign
, HwlComputeSurfaceBaseAlign(pIn
->swizzleMode
));
578 pOut
->pitch
= numMetaBlkX
* metaBlkDim
.w
;
579 pOut
->height
= numMetaBlkY
* metaBlkDim
.h
;
580 pOut
->depth
= numMetaBlkZ
* metaBlkDim
.d
;
582 pOut
->compressBlkWidth
= compressBlkDim
.w
;
583 pOut
->compressBlkHeight
= compressBlkDim
.h
;
584 pOut
->compressBlkDepth
= compressBlkDim
.d
;
586 pOut
->metaBlkWidth
= metaBlkDim
.w
;
587 pOut
->metaBlkHeight
= metaBlkDim
.h
;
588 pOut
->metaBlkDepth
= metaBlkDim
.d
;
590 pOut
->metaBlkNumPerSlice
= numMetaBlkX
* numMetaBlkY
;
591 pOut
->fastClearSizePerSlice
=
592 pOut
->metaBlkNumPerSlice
* numCompressBlkPerMetaBlk
* Min(numFrags
, m_maxCompFrag
);
599 ****************************************************************************************************
600 * Gfx9Lib::HwlGetMaxAlignments
603 * Gets maximum alignments
606 ****************************************************************************************************
608 ADDR_E_RETURNCODE
Gfx9Lib::HwlGetMaxAlignments(
609 ADDR_GET_MAX_ALINGMENTS_OUTPUT
* pOut
///< [out] output structure
612 pOut
->baseAlign
= HwlComputeSurfaceBaseAlign(ADDR_SW_64KB
);
618 ****************************************************************************************************
619 * Gfx9Lib::HwlComputeCmaskAddrFromCoord
622 * Interface function stub of AddrComputeCmaskAddrFromCoord
626 ****************************************************************************************************
628 ADDR_E_RETURNCODE
Gfx9Lib::HwlComputeCmaskAddrFromCoord(
629 const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
630 ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
633 ADDR2_COMPUTE_CMASK_INFO_INPUT input
;
634 ADDR2_COMPUTE_CMASK_INFO_OUTPUT output
;
636 memset(&input
, 0, sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT
));
637 input
.size
= sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT
);
638 input
.cMaskFlags
= pIn
->cMaskFlags
;
639 input
.colorFlags
= pIn
->colorFlags
;
640 input
.unalignedWidth
= Max(pIn
->unalignedWidth
, 1u);
641 input
.unalignedHeight
= Max(pIn
->unalignedHeight
, 1u);
642 input
.numSlices
= Max(pIn
->numSlices
, 1u);
643 input
.swizzleMode
= pIn
->swizzleMode
;
644 input
.resourceType
= pIn
->resourceType
;
646 memset(&output
, 0, sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT
));
647 output
.size
= sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT
);
649 ADDR_E_RETURNCODE returnCode
= ComputeCmaskInfo(&input
, &output
);
651 if (returnCode
== ADDR_OK
)
653 UINT_32 fmaskBpp
= GetFmaskBpp(pIn
->numSamples
, pIn
->numFrags
);
655 UINT_32 fmaskElementBytesLog2
= Log2(fmaskBpp
>> 3);
657 UINT_32 metaBlkWidthLog2
= Log2(output
.metaBlkWidth
);
658 UINT_32 metaBlkHeightLog2
= Log2(output
.metaBlkHeight
);
662 GetMetaEquation(&metaEq
, 0, fmaskElementBytesLog2
, 0, pIn
->cMaskFlags
,
663 Gfx9DataFmask
, pIn
->swizzleMode
, pIn
->resourceType
,
664 metaBlkWidthLog2
, metaBlkHeightLog2
, 0, 3, 3, 0);
666 UINT_32 xb
= pIn
->x
/ output
.metaBlkWidth
;
667 UINT_32 yb
= pIn
->y
/ output
.metaBlkHeight
;
668 UINT_32 zb
= pIn
->slice
;
670 UINT_32 pitchInBlock
= output
.pitch
/ output
.metaBlkWidth
;
671 UINT_32 sliceSizeInBlock
= (output
.height
/ output
.metaBlkHeight
) * pitchInBlock
;
672 UINT_32 blockIndex
= zb
* sliceSizeInBlock
+ yb
* pitchInBlock
+ xb
;
674 UINT_64 address
= metaEq
.solve(pIn
->x
, pIn
->y
, pIn
->slice
, 0, blockIndex
);
676 pOut
->addr
= address
>> 1;
677 pOut
->bitPosition
= static_cast<UINT_32
>((address
& 1) << 2);
680 UINT_32 numPipeBits
= GetPipeLog2ForMetaAddressing(pIn
->cMaskFlags
.pipeAligned
,
683 UINT_64 pipeXor
= static_cast<UINT_64
>(pIn
->pipeXor
& ((1 << numPipeBits
) - 1));
685 pOut
->addr
^= (pipeXor
<< m_pipeInterleaveLog2
);
692 ****************************************************************************************************
693 * Gfx9Lib::HwlComputeHtileAddrFromCoord
696 * Interface function stub of AddrComputeHtileAddrFromCoord
700 ****************************************************************************************************
702 ADDR_E_RETURNCODE
Gfx9Lib::HwlComputeHtileAddrFromCoord(
703 const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
704 ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
707 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
709 if (pIn
->numMipLevels
> 1)
711 returnCode
= ADDR_NOTIMPLEMENTED
;
715 ADDR2_COMPUTE_HTILE_INFO_INPUT input
;
716 ADDR2_COMPUTE_HTILE_INFO_OUTPUT output
;
718 memset(&input
, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT
));
719 input
.size
= sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT
);
720 input
.hTileFlags
= pIn
->hTileFlags
;
721 input
.depthFlags
= pIn
->depthflags
;
722 input
.swizzleMode
= pIn
->swizzleMode
;
723 input
.unalignedWidth
= Max(pIn
->unalignedWidth
, 1u);
724 input
.unalignedHeight
= Max(pIn
->unalignedHeight
, 1u);
725 input
.numSlices
= Max(pIn
->numSlices
, 1u);
726 input
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
728 memset(&output
, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT
));
729 output
.size
= sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT
);
731 returnCode
= ComputeHtileInfo(&input
, &output
);
733 if (returnCode
== ADDR_OK
)
735 UINT_32 elementBytesLog2
= Log2(pIn
->bpp
>> 3);
737 UINT_32 metaBlkWidthLog2
= Log2(output
.metaBlkWidth
);
738 UINT_32 metaBlkHeightLog2
= Log2(output
.metaBlkHeight
);
740 UINT_32 numSamplesLog2
= Log2(pIn
->numSamples
);
744 GetMetaEquation(&metaEq
, 0, elementBytesLog2
, numSamplesLog2
, pIn
->hTileFlags
,
745 Gfx9DataDepthStencil
, pIn
->swizzleMode
, ADDR_RSRC_TEX_2D
,
746 metaBlkWidthLog2
, metaBlkHeightLog2
, 0, 3, 3, 0);
748 UINT_32 xb
= pIn
->x
/ output
.metaBlkWidth
;
749 UINT_32 yb
= pIn
->y
/ output
.metaBlkHeight
;
750 UINT_32 zb
= pIn
->slice
;
752 UINT_32 pitchInBlock
= output
.pitch
/ output
.metaBlkWidth
;
753 UINT_32 sliceSizeInBlock
= (output
.height
/ output
.metaBlkHeight
) * pitchInBlock
;
754 UINT_32 blockIndex
= zb
* sliceSizeInBlock
+ yb
* pitchInBlock
+ xb
;
756 UINT_64 address
= metaEq
.solve(pIn
->x
, pIn
->y
, pIn
->slice
, 0, blockIndex
);
758 pOut
->addr
= address
>> 1;
760 UINT_32 numPipeBits
= GetPipeLog2ForMetaAddressing(pIn
->hTileFlags
.pipeAligned
,
763 UINT_64 pipeXor
= static_cast<UINT_64
>(pIn
->pipeXor
& ((1 << numPipeBits
) - 1));
765 pOut
->addr
^= (pipeXor
<< m_pipeInterleaveLog2
);
773 ****************************************************************************************************
774 * Gfx9Lib::HwlComputeHtileCoordFromAddr
777 * Interface function stub of AddrComputeHtileCoordFromAddr
781 ****************************************************************************************************
783 ADDR_E_RETURNCODE
Gfx9Lib::HwlComputeHtileCoordFromAddr(
784 const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
785 ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
* pOut
///< [out] output structure
788 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
790 if (pIn
->numMipLevels
> 1)
792 returnCode
= ADDR_NOTIMPLEMENTED
;
796 ADDR2_COMPUTE_HTILE_INFO_INPUT input
;
797 ADDR2_COMPUTE_HTILE_INFO_OUTPUT output
;
799 memset(&input
, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT
));
800 input
.size
= sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT
);
801 input
.hTileFlags
= pIn
->hTileFlags
;
802 input
.swizzleMode
= pIn
->swizzleMode
;
803 input
.unalignedWidth
= Max(pIn
->unalignedWidth
, 1u);
804 input
.unalignedHeight
= Max(pIn
->unalignedHeight
, 1u);
805 input
.numSlices
= Max(pIn
->numSlices
, 1u);
806 input
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
808 memset(&output
, 0, sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT
));
809 output
.size
= sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT
);
811 returnCode
= ComputeHtileInfo(&input
, &output
);
813 if (returnCode
== ADDR_OK
)
815 UINT_32 elementBytesLog2
= Log2(pIn
->bpp
>> 3);
817 UINT_32 metaBlkWidthLog2
= Log2(output
.metaBlkWidth
);
818 UINT_32 metaBlkHeightLog2
= Log2(output
.metaBlkHeight
);
820 UINT_32 numSamplesLog2
= Log2(pIn
->numSamples
);
824 GetMetaEquation(&metaEq
, 0, elementBytesLog2
, numSamplesLog2
, pIn
->hTileFlags
,
825 Gfx9DataDepthStencil
, pIn
->swizzleMode
, ADDR_RSRC_TEX_2D
,
826 metaBlkWidthLog2
, metaBlkHeightLog2
, 0, 3, 3, 0);
828 UINT_32 numPipeBits
= GetPipeLog2ForMetaAddressing(pIn
->hTileFlags
.pipeAligned
,
831 UINT_64 pipeXor
= static_cast<UINT_64
>(pIn
->pipeXor
& ((1 << numPipeBits
) - 1));
833 UINT_64 nibbleAddress
= (pIn
->addr
^ (pipeXor
<< m_pipeInterleaveLog2
)) << 1;
835 UINT_32 pitchInBlock
= output
.pitch
/ output
.metaBlkWidth
;
836 UINT_32 sliceSizeInBlock
= (output
.height
/ output
.metaBlkHeight
) * pitchInBlock
;
838 UINT_32 x
, y
, z
, s
, m
;
840 metaEq
.solveAddr(nibbleAddress
, sliceSizeInBlock
, x
, y
, z
, s
, m
);
842 pOut
->slice
= m
/ sliceSizeInBlock
;
843 pOut
->y
= ((m
% sliceSizeInBlock
) / pitchInBlock
) * output
.metaBlkHeight
+ y
;
844 pOut
->x
= (m
% pitchInBlock
) * output
.metaBlkWidth
+ x
;
852 ****************************************************************************************************
853 * Gfx9Lib::HwlInitGlobalParams
856 * Initializes global parameters
859 * TRUE if all settings are valid
861 ****************************************************************************************************
863 BOOL_32
Gfx9Lib::HwlInitGlobalParams(
864 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
866 BOOL_32 valid
= TRUE
;
868 if (m_settings
.isArcticIsland
)
870 GB_ADDR_CONFIG gbAddrConfig
;
872 gbAddrConfig
.u32All
= pCreateIn
->regValue
.gbAddrConfig
;
874 // These values are copied from CModel code
875 switch (gbAddrConfig
.bits
.NUM_PIPES
)
877 case ADDR_CONFIG_1_PIPE
:
881 case ADDR_CONFIG_2_PIPE
:
885 case ADDR_CONFIG_4_PIPE
:
889 case ADDR_CONFIG_8_PIPE
:
893 case ADDR_CONFIG_16_PIPE
:
897 case ADDR_CONFIG_32_PIPE
:
905 switch (gbAddrConfig
.bits
.PIPE_INTERLEAVE_SIZE
)
907 case ADDR_CONFIG_PIPE_INTERLEAVE_256B
:
908 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_256B
;
909 m_pipeInterleaveLog2
= 8;
911 case ADDR_CONFIG_PIPE_INTERLEAVE_512B
:
912 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_512B
;
913 m_pipeInterleaveLog2
= 9;
915 case ADDR_CONFIG_PIPE_INTERLEAVE_1KB
:
916 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_1KB
;
917 m_pipeInterleaveLog2
= 10;
919 case ADDR_CONFIG_PIPE_INTERLEAVE_2KB
:
920 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_2KB
;
921 m_pipeInterleaveLog2
= 11;
927 switch (gbAddrConfig
.bits
.NUM_BANKS
)
929 case ADDR_CONFIG_1_BANK
:
933 case ADDR_CONFIG_2_BANK
:
937 case ADDR_CONFIG_4_BANK
:
941 case ADDR_CONFIG_8_BANK
:
945 case ADDR_CONFIG_16_BANK
:
953 switch (gbAddrConfig
.bits
.NUM_SHADER_ENGINES
)
955 case ADDR_CONFIG_1_SHADER_ENGINE
:
959 case ADDR_CONFIG_2_SHADER_ENGINE
:
963 case ADDR_CONFIG_4_SHADER_ENGINE
:
967 case ADDR_CONFIG_8_SHADER_ENGINE
:
975 switch (gbAddrConfig
.bits
.NUM_RB_PER_SE
)
977 case ADDR_CONFIG_1_RB_PER_SHADER_ENGINE
:
981 case ADDR_CONFIG_2_RB_PER_SHADER_ENGINE
:
985 case ADDR_CONFIG_4_RB_PER_SHADER_ENGINE
:
993 switch (gbAddrConfig
.bits
.MAX_COMPRESSED_FRAGS
)
995 case ADDR_CONFIG_1_MAX_COMPRESSED_FRAGMENTS
:
997 m_maxCompFragLog2
= 0;
999 case ADDR_CONFIG_2_MAX_COMPRESSED_FRAGMENTS
:
1001 m_maxCompFragLog2
= 1;
1003 case ADDR_CONFIG_4_MAX_COMPRESSED_FRAGMENTS
:
1005 m_maxCompFragLog2
= 2;
1007 case ADDR_CONFIG_8_MAX_COMPRESSED_FRAGMENTS
:
1009 m_maxCompFragLog2
= 3;
1015 m_blockVarSizeLog2
= pCreateIn
->regValue
.blockVarSizeLog2
;
1016 ADDR_ASSERT((m_blockVarSizeLog2
== 0) ||
1017 ((m_blockVarSizeLog2
>= 17u) && (m_blockVarSizeLog2
<= 20u)));
1018 m_blockVarSizeLog2
= Min(Max(17u, m_blockVarSizeLog2
), 20u);
1023 ADDR_NOT_IMPLEMENTED();
1028 InitEquationTable();
1035 ****************************************************************************************************
1036 * Gfx9Lib::HwlConvertChipFamily
1039 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
1042 ****************************************************************************************************
1044 ChipFamily
Gfx9Lib::HwlConvertChipFamily(
1045 UINT_32 uChipFamily
, ///< [in] chip family defined in atiih.h
1046 UINT_32 uChipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
1048 ChipFamily family
= ADDR_CHIP_FAMILY_AI
;
1050 switch (uChipFamily
)
1053 m_settings
.isArcticIsland
= 1;
1054 m_settings
.isVega10
= ASICREV_IS_VEGA10_P(uChipRevision
);
1056 if (m_settings
.isVega10
)
1058 m_settings
.isDce12
= 1;
1061 // Bug ID DEGGIGX90-1056
1062 m_settings
.metaBaseAlignFix
= 1;
1066 ADDR_ASSERT(!"This should be a Fusion");
1074 ****************************************************************************************************
1075 * Gfx9Lib::InitRbEquation
1081 ****************************************************************************************************
1083 VOID
Gfx9Lib::GetRbEquation(
1084 CoordEq
* pRbEq
, ///< [out] rb equation
1085 UINT_32 numRbPerSeLog2
, ///< [in] number of rb per shader engine
1086 UINT_32 numSeLog2
) ///< [in] number of shader engine
1088 // RB's are distributed on 16x16, except when we have 1 rb per se, in which case its 32x32
1089 UINT_32 rbRegion
= (numRbPerSeLog2
== 0) ? 5 : 4;
1090 Coordinate
cx('x', rbRegion
);
1091 Coordinate
cy('y', rbRegion
);
1094 UINT_32 numRbTotalLog2
= numRbPerSeLog2
+ numSeLog2
;
1096 // Clear the rb equation
1098 pRbEq
->resize(numRbTotalLog2
);
1100 if ((numSeLog2
> 0) && (numRbPerSeLog2
== 1))
1102 // Special case when more than 1 SE, and 2 RB per SE
1103 (*pRbEq
)[0].add(cx
);
1104 (*pRbEq
)[0].add(cy
);
1107 (*pRbEq
)[0].add(cy
);
1111 UINT_32 numBits
= 2 * (numRbTotalLog2
- start
);
1113 for (UINT_32 i
= 0; i
< numBits
; i
++)
1116 start
+ (((start
+ i
) >= numRbTotalLog2
) ? (2 * (numRbTotalLog2
- start
) - i
- 1) : i
);
1120 (*pRbEq
)[idx
].add(cx
);
1125 (*pRbEq
)[idx
].add(cy
);
1132 ****************************************************************************************************
1133 * Gfx9Lib::GetDataEquation
1136 * Get data equation for fmask and Z
1139 ****************************************************************************************************
1141 VOID
Gfx9Lib::GetDataEquation(
1142 CoordEq
* pDataEq
, ///< [out] data surface equation
1143 Gfx9DataType dataSurfaceType
, ///< [in] data surface type
1144 AddrSwizzleMode swizzleMode
, ///< [in] data surface swizzle mode
1145 AddrResourceType resourceType
, ///< [in] data surface resource type
1146 UINT_32 elementBytesLog2
, ///< [in] data surface element bytes
1147 UINT_32 numSamplesLog2
) ///< [in] data surface sample count
1150 Coordinate
cx('x', 0);
1151 Coordinate
cy('y', 0);
1152 Coordinate
cz('z', 0);
1153 Coordinate
cs('s', 0);
1155 // Clear the equation
1157 pDataEq
->resize(27);
1159 if (dataSurfaceType
== Gfx9DataColor
)
1161 if (IsLinear(swizzleMode
))
1163 Coordinate
cm('m', 0);
1165 pDataEq
->resize(49);
1167 for (UINT_32 i
= 0; i
< 49; i
++)
1169 (*pDataEq
)[i
].add(cm
);
1173 else if (IsThick(resourceType
, swizzleMode
))
1175 // Color 3d_S and 3d_Z modes, 3d_D is same as color 2d
1177 if (IsStandardSwizzle(resourceType
, swizzleMode
))
1179 // Standard 3d swizzle
1180 // Fill in bottom x bits
1181 for (i
= elementBytesLog2
; i
< 4; i
++)
1183 (*pDataEq
)[i
].add(cx
);
1186 // Fill in 2 bits of y and then z
1187 for (i
= 4; i
< 6; i
++)
1189 (*pDataEq
)[i
].add(cy
);
1192 for (i
= 6; i
< 8; i
++)
1194 (*pDataEq
)[i
].add(cz
);
1197 if (elementBytesLog2
< 2)
1199 // fill in z & y bit
1200 (*pDataEq
)[8].add(cz
);
1201 (*pDataEq
)[9].add(cy
);
1205 else if (elementBytesLog2
== 2)
1207 // fill in y and x bit
1208 (*pDataEq
)[8].add(cy
);
1209 (*pDataEq
)[9].add(cx
);
1216 (*pDataEq
)[8].add(cx
);
1218 (*pDataEq
)[9].add(cx
);
1225 UINT_32 m2dEnd
= (elementBytesLog2
==0) ? 3 : ((elementBytesLog2
< 4) ? 4 : 5);
1226 UINT_32 numZs
= (elementBytesLog2
== 0 || elementBytesLog2
== 4) ?
1227 2 : ((elementBytesLog2
== 1) ? 3 : 1);
1228 pDataEq
->mort2d(cx
, cy
, elementBytesLog2
, m2dEnd
);
1229 for (i
= m2dEnd
+ 1; i
<= m2dEnd
+ numZs
; i
++)
1231 (*pDataEq
)[i
].add(cz
);
1234 if ((elementBytesLog2
== 0) || (elementBytesLog2
== 3))
1237 (*pDataEq
)[6].add(cx
);
1238 (*pDataEq
)[7].add(cz
);
1242 else if (elementBytesLog2
== 2)
1245 (*pDataEq
)[6].add(cy
);
1246 (*pDataEq
)[7].add(cz
);
1251 (*pDataEq
)[8].add(cy
);
1252 (*pDataEq
)[9].add(cx
);
1256 // Fill in bit 10 and up
1257 pDataEq
->mort3d( cz
, cy
, cx
, 10 );
1259 else if (IsThin(resourceType
, swizzleMode
))
1261 UINT_32 blockSizeLog2
= GetBlockSizeLog2(swizzleMode
);
1263 UINT_32 microYBits
= (8 - elementBytesLog2
) / 2;
1264 UINT_32 tileSplitStart
= blockSizeLog2
- numSamplesLog2
;
1266 // Fill in bottom x bits
1267 for (i
= elementBytesLog2
; i
< 4; i
++)
1269 (*pDataEq
)[i
].add(cx
);
1272 // Fill in bottom y bits
1273 for (i
= 4; i
< 4 + microYBits
; i
++)
1275 (*pDataEq
)[i
].add(cy
);
1278 // Fill in last of the micro_x bits
1279 for (i
= 4 + microYBits
; i
< 8; i
++)
1281 (*pDataEq
)[i
].add(cx
);
1284 // Fill in x/y bits below sample split
1285 pDataEq
->mort2d(cy
, cx
, 8, tileSplitStart
- 1);
1286 // Fill in sample bits
1287 for (i
= 0; i
< numSamplesLog2
; i
++)
1290 (*pDataEq
)[tileSplitStart
+ i
].add(cs
);
1292 // Fill in x/y bits above sample split
1293 if ((numSamplesLog2
& 1) ^ (blockSizeLog2
& 1))
1295 pDataEq
->mort2d(cx
, cy
, blockSizeLog2
);
1299 pDataEq
->mort2d(cy
, cx
, blockSizeLog2
);
1304 ADDR_ASSERT_ALWAYS();
1310 UINT_32 sampleStart
= elementBytesLog2
;
1311 UINT_32 pixelStart
= elementBytesLog2
+ numSamplesLog2
;
1312 UINT_32 ymajStart
= 6 + numSamplesLog2
;
1314 for (UINT_32 s
= 0; s
< numSamplesLog2
; s
++)
1317 (*pDataEq
)[sampleStart
+ s
].add(cs
);
1320 // Put in the x-major order pixel bits
1321 pDataEq
->mort2d(cx
, cy
, pixelStart
, ymajStart
- 1);
1322 // Put in the y-major order pixel bits
1323 pDataEq
->mort2d(cy
, cx
, ymajStart
);
1328 ****************************************************************************************************
1329 * Gfx9Lib::GetPipeEquation
1335 ****************************************************************************************************
1337 VOID
Gfx9Lib::GetPipeEquation(
1338 CoordEq
* pPipeEq
, ///< [out] pipe equation
1339 CoordEq
* pDataEq
, ///< [in] data equation
1340 UINT_32 pipeInterleaveLog2
, ///< [in] pipe interleave
1341 UINT_32 numPipeLog2
, ///< [in] number of pipes
1342 UINT_32 numSamplesLog2
, ///< [in] data surface sample count
1343 Gfx9DataType dataSurfaceType
, ///< [in] data surface type
1344 AddrSwizzleMode swizzleMode
, ///< [in] data surface swizzle mode
1345 AddrResourceType resourceType
///< [in] data surface resource type
1348 UINT_32 blockSizeLog2
= GetBlockSizeLog2(swizzleMode
);
1351 pDataEq
->copy(dataEq
);
1353 if (dataSurfaceType
== Gfx9DataColor
)
1355 INT_32 shift
= static_cast<INT_32
>(numSamplesLog2
);
1356 dataEq
.shift(-shift
, blockSizeLog2
- numSamplesLog2
);
1359 dataEq
.copy(*pPipeEq
, pipeInterleaveLog2
, numPipeLog2
);
1361 // This section should only apply to z/stencil, maybe fmask
1362 // If the pipe bit is below the comp block size,
1363 // then keep moving up the address until we find a bit that is above
1364 UINT_32 pipeStart
= 0;
1366 if (dataSurfaceType
!= Gfx9DataColor
)
1368 Coordinate
tileMin('x', 3);
1370 while (dataEq
[pipeInterleaveLog2
+ pipeStart
][0] < tileMin
)
1375 // if pipe is 0, then the first pipe bit is above the comp block size,
1376 // so we don't need to do anything
1377 // Note, this if condition is not necessary, since if we execute the loop when pipe==0,
1378 // we will get the same pipe equation
1381 for (UINT_32 i
= 0; i
< numPipeLog2
; i
++)
1383 // Copy the jth bit above pipe interleave to the current pipe equation bit
1384 dataEq
[pipeInterleaveLog2
+ pipeStart
+ i
].copyto((*pPipeEq
)[i
]);
1389 if (IsPrt(swizzleMode
))
1391 // Clear out bits above the block size if prt's are enabled
1392 dataEq
.resize(blockSizeLog2
);
1396 if (IsXor(swizzleMode
))
1400 if (IsThick(resourceType
, swizzleMode
))
1404 dataEq
.copy(xorMask2
, pipeInterleaveLog2
+ numPipeLog2
, 2 * numPipeLog2
);
1406 xorMask
.resize(numPipeLog2
);
1408 for (UINT_32 pipeIdx
= 0; pipeIdx
< numPipeLog2
; pipeIdx
++)
1410 xorMask
[pipeIdx
].add(xorMask2
[2 * pipeIdx
]);
1411 xorMask
[pipeIdx
].add(xorMask2
[2 * pipeIdx
+ 1]);
1416 // Xor in the bits above the pipe+gpu bits
1417 dataEq
.copy(xorMask
, pipeInterleaveLog2
+ pipeStart
+ numPipeLog2
, numPipeLog2
);
1419 if ((numSamplesLog2
== 0) && (IsPrt(swizzleMode
) == FALSE
))
1423 // if 1xaa and not prt, then xor in the z bits
1425 xorMask2
.resize(numPipeLog2
);
1426 for (UINT_32 pipeIdx
= 0; pipeIdx
< numPipeLog2
; pipeIdx
++)
1428 co
.set('z', numPipeLog2
- 1 - pipeIdx
);
1429 xorMask2
[pipeIdx
].add(co
);
1432 pPipeEq
->xorin(xorMask2
);
1437 pPipeEq
->xorin(xorMask
);
1442 ****************************************************************************************************
1443 * Gfx9Lib::GetMetaEquation
1446 * Get meta equation for cmask/htile/DCC
1449 ****************************************************************************************************
1451 VOID
Gfx9Lib::GetMetaEquation(
1452 CoordEq
* pMetaEq
, ///< [out] meta equation
1453 UINT_32 maxMip
, ///< [in] max mip Id
1454 UINT_32 elementBytesLog2
, ///< [in] data surface element bytes
1455 UINT_32 numSamplesLog2
, ///< [in] data surface sample count
1456 ADDR2_META_FLAGS metaFlag
, ///< [in] meta falg
1457 Gfx9DataType dataSurfaceType
, ///< [in] data surface type
1458 AddrSwizzleMode swizzleMode
, ///< [in] data surface swizzle mode
1459 AddrResourceType resourceType
, ///< [in] data surface resource type
1460 UINT_32 metaBlkWidthLog2
, ///< [in] meta block width
1461 UINT_32 metaBlkHeightLog2
, ///< [in] meta block height
1462 UINT_32 metaBlkDepthLog2
, ///< [in] meta block depth
1463 UINT_32 compBlkWidthLog2
, ///< [in] compress block width
1464 UINT_32 compBlkHeightLog2
, ///< [in] compress block height
1465 UINT_32 compBlkDepthLog2
) ///< [in] compress block depth
1468 UINT_32 numPipeTotalLog2
= GetPipeLog2ForMetaAddressing(metaFlag
.pipeAligned
, swizzleMode
);
1469 UINT_32 pipeInterleaveLog2
= m_pipeInterleaveLog2
;
1470 //UINT_32 blockSizeLog2 = GetBlockSizeLog2(swizzleMode);
1472 // Get the correct data address and rb equation
1474 GetDataEquation(&dataEq
, dataSurfaceType
, swizzleMode
, resourceType
,
1475 elementBytesLog2
, numSamplesLog2
);
1477 // Get pipe and rb equations
1478 CoordEq pipeEquation
;
1479 GetPipeEquation(&pipeEquation
, &dataEq
, pipeInterleaveLog2
, numPipeTotalLog2
,
1480 numSamplesLog2
, dataSurfaceType
, swizzleMode
, resourceType
);
1481 numPipeTotalLog2
= pipeEquation
.getsize();
1483 if (metaFlag
.linear
)
1485 // Linear metadata supporting was removed for GFX9! No one can use this feature.
1486 ADDR_ASSERT_ALWAYS();
1488 ADDR_ASSERT(dataSurfaceType
== Gfx9DataColor
);
1490 dataEq
.copy(*pMetaEq
);
1492 if (IsLinear(swizzleMode
))
1494 if (metaFlag
.pipeAligned
)
1496 // Remove the pipe bits
1497 INT_32 shift
= static_cast<INT_32
>(numPipeTotalLog2
);
1498 pMetaEq
->shift(-shift
, pipeInterleaveLog2
);
1500 // Divide by comp block size, which for linear (which is always color) is 256 B
1503 if (metaFlag
.pipeAligned
)
1505 // Put pipe bits back in
1506 pMetaEq
->shift(numPipeTotalLog2
, pipeInterleaveLog2
);
1508 for (UINT_32 i
= 0; i
< numPipeTotalLog2
; i
++)
1510 pipeEquation
[i
].copyto((*pMetaEq
)[pipeInterleaveLog2
+ i
]);
1519 UINT_32 maxCompFragLog2
= static_cast<INT_32
>(m_maxCompFragLog2
);
1520 UINT_32 compFragLog2
=
1521 ((dataSurfaceType
== Gfx9DataColor
) && (numSamplesLog2
> maxCompFragLog2
)) ?
1522 maxCompFragLog2
: numSamplesLog2
;
1524 UINT_32 uncompFragLog2
= numSamplesLog2
- compFragLog2
;
1526 // Make sure the metaaddr is cleared
1528 pMetaEq
->resize(27);
1530 if (IsThick(resourceType
, swizzleMode
))
1532 Coordinate
cx('x', 0);
1533 Coordinate
cy('y', 0);
1534 Coordinate
cz('z', 0);
1538 pMetaEq
->mort3d(cy
, cx
, cz
);
1542 pMetaEq
->mort3d(cx
, cy
, cz
);
1547 Coordinate
cx('x', 0);
1548 Coordinate
cy('y', 0);
1553 pMetaEq
->mort2d(cy
, cx
, compFragLog2
);
1557 pMetaEq
->mort2d(cx
, cy
, compFragLog2
);
1560 //------------------------------------------------------------------------------------------------------------------------
1561 // Put the compressible fragments at the lsb
1562 // the uncompressible frags will be at the msb of the micro address
1563 //------------------------------------------------------------------------------------------------------------------------
1564 for (UINT_32 s
= 0; s
< compFragLog2
; s
++)
1567 (*pMetaEq
)[s
].add(cs
);
1571 // Keep a copy of the pipe equations
1572 CoordEq origPipeEquation
;
1573 pipeEquation
.copy(origPipeEquation
);
1576 // filter out everything under the compressed block size
1577 co
.set('x', compBlkWidthLog2
);
1578 pMetaEq
->Filter('<', co
, 0, 'x');
1579 co
.set('y', compBlkHeightLog2
);
1580 pMetaEq
->Filter('<', co
, 0, 'y');
1581 co
.set('z', compBlkDepthLog2
);
1582 pMetaEq
->Filter('<', co
, 0, 'z');
1584 // For non-color, filter out sample bits
1585 if (dataSurfaceType
!= Gfx9DataColor
)
1588 pMetaEq
->Filter('<', co
, 0, 's');
1591 // filter out everything above the metablock size
1592 co
.set('x', metaBlkWidthLog2
- 1);
1593 pMetaEq
->Filter('>', co
, 0, 'x');
1594 co
.set('y', metaBlkHeightLog2
- 1);
1595 pMetaEq
->Filter('>', co
, 0, 'y');
1596 co
.set('z', metaBlkDepthLog2
- 1);
1597 pMetaEq
->Filter('>', co
, 0, 'z');
1599 // filter out everything above the metablock size for the channel bits
1600 co
.set('x', metaBlkWidthLog2
- 1);
1601 pipeEquation
.Filter('>', co
, 0, 'x');
1602 co
.set('y', metaBlkHeightLog2
- 1);
1603 pipeEquation
.Filter('>', co
, 0, 'y');
1604 co
.set('z', metaBlkDepthLog2
- 1);
1605 pipeEquation
.Filter('>', co
, 0, 'z');
1607 // Make sure we still have the same number of channel bits
1608 if (pipeEquation
.getsize() != numPipeTotalLog2
)
1610 ADDR_ASSERT_ALWAYS();
1613 // Loop through all channel and rb bits,
1614 // and make sure these components exist in the metadata address
1615 for (UINT_32 i
= 0; i
< numPipeTotalLog2
; i
++)
1617 for (UINT_32 j
= pipeEquation
[i
].getsize(); j
> 0; j
--)
1619 if (pMetaEq
->Exists(pipeEquation
[i
][j
- 1]) == FALSE
)
1621 ADDR_ASSERT_ALWAYS();
1626 UINT_32 numSeLog2
= metaFlag
.rbAligned
? m_seLog2
: 0;
1627 UINT_32 numRbPeSeLog2
= metaFlag
.rbAligned
? m_rbPerSeLog2
: 0;
1628 CoordEq origRbEquation
;
1630 GetRbEquation(&origRbEquation
, numRbPeSeLog2
, numSeLog2
);
1632 CoordEq rbEquation
= origRbEquation
;
1634 UINT_32 numRbTotalLog2
= numRbPeSeLog2
+ numSeLog2
;
1636 for (UINT_32 i
= 0; i
< numRbTotalLog2
; i
++)
1638 for (UINT_32 j
= rbEquation
[i
].getsize(); j
> 0; j
--)
1640 if (pMetaEq
->Exists(rbEquation
[i
][j
- 1]) == FALSE
)
1642 ADDR_ASSERT_ALWAYS();
1647 // Loop through each rb id bit; if it is equal to any of the filtered channel bits, clear it
1648 for (UINT_32 i
= 0; i
< numRbTotalLog2
; i
++)
1650 for (UINT_32 j
= 0; j
< numPipeTotalLog2
; j
++)
1652 if (rbEquation
[i
] == pipeEquation
[j
])
1654 rbEquation
[i
].Clear();
1659 // Loop through each bit of the channel, get the smallest coordinate,
1660 // and remove it from the metaaddr, and rb_equation
1661 for (UINT_32 i
= 0; i
< numPipeTotalLog2
; i
++)
1663 pipeEquation
[i
].getsmallest(co
);
1665 UINT_32 old_size
= pMetaEq
->getsize();
1666 pMetaEq
->Filter('=', co
);
1667 UINT_32 new_size
= pMetaEq
->getsize();
1668 if (new_size
!= old_size
-1)
1670 ADDR_ASSERT_ALWAYS();
1672 pipeEquation
.remove(co
);
1673 for (UINT_32 j
= 0; j
< numRbTotalLog2
; j
++)
1675 if (rbEquation
[j
].remove(co
))
1677 // if we actually removed something from this bit, then add the remaining
1678 // channel bits, as these can be removed for this bit
1679 for (UINT_32 k
= 0; k
< pipeEquation
[i
].getsize(); k
++)
1681 if (pipeEquation
[i
][k
] != co
)
1683 rbEquation
[j
].add(pipeEquation
[i
][k
]);
1690 // Loop through the rb bits and see what remain;
1691 // filter out the smallest coordinate if it remains
1692 UINT_32 rbBitsLeft
= 0;
1693 for (UINT_32 i
= 0; i
< numRbTotalLog2
; i
++)
1695 if (rbEquation
[i
].getsize() > 0)
1698 rbEquation
[i
].getsmallest(co
);
1699 UINT_32 old_size
= pMetaEq
->getsize();
1700 pMetaEq
->Filter('=', co
);
1701 UINT_32 new_size
= pMetaEq
->getsize();
1702 if (new_size
!= old_size
- 1)
1706 for (UINT_32 j
= i
+ 1; j
< numRbTotalLog2
; j
++)
1708 if (rbEquation
[j
].remove(co
))
1710 // if we actually removed something from this bit, then add the remaining
1711 // rb bits, as these can be removed for this bit
1712 for (UINT_32 k
= 0; k
< rbEquation
[i
].getsize(); k
++)
1714 if (rbEquation
[i
][k
] != co
)
1716 rbEquation
[j
].add(rbEquation
[i
][k
]);
1724 // capture the size of the metaaddr
1725 UINT_32 metaSize
= pMetaEq
->getsize();
1726 // resize to 49 bits...make this a nibble address
1727 pMetaEq
->resize(49);
1728 // Concatenate the macro address above the current address
1729 for (UINT_32 i
= metaSize
, j
= 0; i
< 49; i
++, j
++)
1732 (*pMetaEq
)[i
].add(co
);
1735 // Multiply by meta element size (in nibbles)
1736 if (dataSurfaceType
== Gfx9DataColor
)
1740 else if (dataSurfaceType
== Gfx9DataDepthStencil
)
1745 //------------------------------------------------------------------------------------------
1746 // Note the pipeInterleaveLog2+1 is because address is a nibble address
1747 // Shift up from pipe interleave number of channel
1748 // and rb bits left, and uncompressed fragments
1749 //------------------------------------------------------------------------------------------
1751 pMetaEq
->shift(numPipeTotalLog2
+ rbBitsLeft
+ uncompFragLog2
, pipeInterleaveLog2
+ 1);
1753 // Put in the channel bits
1754 for (UINT_32 i
= 0; i
< numPipeTotalLog2
; i
++)
1756 origPipeEquation
[i
].copyto((*pMetaEq
)[pipeInterleaveLog2
+1 + i
]);
1759 // Put in remaining rb bits
1760 for (UINT_32 i
= 0, j
= 0; j
< rbBitsLeft
; i
= (i
+ 1) % numRbTotalLog2
)
1762 if (rbEquation
[i
].getsize() > 0)
1764 origRbEquation
[i
].copyto((*pMetaEq
)[pipeInterleaveLog2
+ 1 + numPipeTotalLog2
+ j
]);
1765 // Mark any rb bit we add in to the rb mask
1770 //------------------------------------------------------------------------------------------
1771 // Put in the uncompressed fragment bits
1772 //------------------------------------------------------------------------------------------
1773 for (UINT_32 i
= 0; i
< uncompFragLog2
; i
++)
1775 co
.set('s', compFragLog2
+ i
);
1776 (*pMetaEq
)[pipeInterleaveLog2
+ 1 + numPipeTotalLog2
+ rbBitsLeft
+ i
].add(co
);
1782 ****************************************************************************************************
1783 * Gfx9Lib::IsEquationSupported
1786 * Check if equation is supported for given swizzle mode and resource type.
1790 ****************************************************************************************************
1792 BOOL_32
Gfx9Lib::IsEquationSupported(
1793 AddrResourceType rsrcType
,
1794 AddrSwizzleMode swMode
,
1795 UINT_32 elementBytesLog2
) const
1797 BOOL_32 supported
= (elementBytesLog2
< MaxElementBytesLog2
) &&
1798 (IsLinear(swMode
) == FALSE
) &&
1799 ((IsTex2d(rsrcType
) == TRUE
) ||
1800 ((IsTex3d(rsrcType
) == TRUE
) &&
1801 (IsRotateSwizzle(swMode
) == FALSE
) &&
1802 (IsBlock256b(swMode
) == FALSE
)));
1808 ****************************************************************************************************
1809 * Gfx9Lib::InitEquationTable
1812 * Initialize Equation table.
1816 ****************************************************************************************************
1818 VOID
Gfx9Lib::InitEquationTable()
1820 memset(m_equationTable
, 0, sizeof(m_equationTable
));
1822 // Loop all possible resource type (2D/3D)
1823 for (UINT_32 rsrcTypeIdx
= 0; rsrcTypeIdx
< MaxRsrcType
; rsrcTypeIdx
++)
1825 AddrResourceType rsrcType
= static_cast<AddrResourceType
>(rsrcTypeIdx
+ ADDR_RSRC_TEX_2D
);
1827 // Loop all possible swizzle mode
1828 for (UINT_32 swModeIdx
= 0; swModeIdx
< MaxSwMode
; swModeIdx
++)
1830 AddrSwizzleMode swMode
= static_cast<AddrSwizzleMode
>(swModeIdx
);
1832 // Loop all possible bpp
1833 for (UINT_32 bppIdx
= 0; bppIdx
< MaxElementBytesLog2
; bppIdx
++)
1835 UINT_32 equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
1837 // Check if the input is supported
1838 if (IsEquationSupported(rsrcType
, swMode
, bppIdx
))
1840 ADDR_EQUATION equation
;
1841 ADDR_E_RETURNCODE retCode
;
1843 memset(&equation
, 0, sizeof(ADDR_EQUATION
));
1845 // Generate the equation
1846 if (IsBlock256b(swMode
) && IsTex2d(rsrcType
))
1848 retCode
= ComputeBlock256Equation(rsrcType
, swMode
, bppIdx
, &equation
);
1850 else if (IsThin(rsrcType
, swMode
))
1852 retCode
= ComputeThinEquation(rsrcType
, swMode
, bppIdx
, &equation
);
1856 retCode
= ComputeThickEquation(rsrcType
, swMode
, bppIdx
, &equation
);
1859 // Only fill the equation into the table if the return code is ADDR_OK,
1860 // otherwise if the return code is not ADDR_OK, it indicates this is not
1861 // a valid input, we do nothing but just fill invalid equation index
1862 // into the lookup table.
1863 if (retCode
== ADDR_OK
)
1865 equationIndex
= m_numEquations
;
1866 ADDR_ASSERT(equationIndex
< EquationTableSize
);
1868 m_equationTable
[equationIndex
] = equation
;
1874 // Fill the index into the lookup table, if the combination is not supported
1875 // fill the invalid equation index
1876 m_equationLookupTable
[rsrcTypeIdx
][swModeIdx
][bppIdx
] = equationIndex
;
1883 ****************************************************************************************************
1884 * Gfx9Lib::HwlGetEquationIndex
1887 * Interface function stub of GetEquationIndex
1891 ****************************************************************************************************
1893 UINT_32
Gfx9Lib::HwlGetEquationIndex(
1894 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
,
1895 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
1898 AddrResourceType rsrcType
= pIn
->resourceType
;
1899 AddrSwizzleMode swMode
= pIn
->swizzleMode
;
1900 UINT_32 elementBytesLog2
= Log2(pIn
->bpp
>> 3);
1901 UINT_32 numMipLevels
= pIn
->numMipLevels
;
1902 ADDR2_MIP_INFO
* pMipInfo
= pOut
->pMipInfo
;
1904 UINT_32 index
= ADDR_INVALID_EQUATION_INDEX
;
1906 BOOL_32 eqSupported
= (pOut
->firstMipInTail
== FALSE
) &&
1907 IsEquationSupported(rsrcType
, swMode
, elementBytesLog2
);
1909 UINT_32 rsrcTypeIdx
= static_cast<UINT_32
>(rsrcType
) - 1;
1910 UINT_32 swModeIdx
= static_cast<UINT_32
>(swMode
);
1914 index
= m_equationLookupTable
[rsrcTypeIdx
][swModeIdx
][elementBytesLog2
];
1916 if (pMipInfo
!= NULL
)
1918 pMipInfo
->equationIndex
= index
;
1919 pMipInfo
->mipOffsetXBytes
= 0;
1920 pMipInfo
->mipOffsetYPixel
= 0;
1921 pMipInfo
->mipOffsetZPixel
= 0;
1922 pMipInfo
->postSwizzleOffset
= 0;
1924 /*static const UINT_32 Prt_Xor_Gap =
1925 static_cast<UINT_32>(ADDR_SW_64KB_Z_T) - static_cast<UINT_32>(ADDR_SW_64KB_Z);*/
1927 for (UINT_32 i
= 1; i
< numMipLevels
; i
++)
1929 Dim3d mipStartPos
= {0};
1930 UINT_32 mipTailOffset
= 0;
1932 mipStartPos
= GetMipStartPos(rsrcType
,
1943 UINT_32 mipSwModeIdx
= swModeIdx
;
1945 pMipInfo
[i
].equationIndex
=
1946 m_equationLookupTable
[rsrcTypeIdx
][mipSwModeIdx
][elementBytesLog2
];
1947 pMipInfo
[i
].mipOffsetXBytes
= mipStartPos
.w
* pOut
->blockWidth
* (pOut
->bpp
>> 3);
1948 pMipInfo
[i
].mipOffsetYPixel
= mipStartPos
.h
* pOut
->blockHeight
;
1949 pMipInfo
[i
].mipOffsetZPixel
= mipStartPos
.d
* pOut
->blockSlices
;
1950 pMipInfo
[i
].postSwizzleOffset
= mipTailOffset
;
1954 else if (pMipInfo
!= NULL
)
1956 for (UINT_32 i
= 0; i
< numMipLevels
; i
++)
1958 pMipInfo
[i
].equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
1959 pMipInfo
[i
].mipOffsetXBytes
= 0;
1960 pMipInfo
[i
].mipOffsetYPixel
= 0;
1961 pMipInfo
[i
].mipOffsetZPixel
= 0;
1962 pMipInfo
[i
].postSwizzleOffset
= 0;
1970 ****************************************************************************************************
1971 * Gfx9Lib::HwlComputeBlock256Equation
1974 * Interface function stub of ComputeBlock256Equation
1978 ****************************************************************************************************
1980 ADDR_E_RETURNCODE
Gfx9Lib::HwlComputeBlock256Equation(
1981 AddrResourceType rsrcType
,
1982 AddrSwizzleMode swMode
,
1983 UINT_32 elementBytesLog2
,
1984 ADDR_EQUATION
* pEquation
) const
1986 ADDR_E_RETURNCODE ret
= ADDR_OK
;
1988 pEquation
->numBits
= 8;
1991 for (; i
< elementBytesLog2
; i
++)
1993 InitChannel(1, 0 , i
, &pEquation
->addr
[i
]);
1996 ADDR_CHANNEL_SETTING
* pixelBit
= &pEquation
->addr
[elementBytesLog2
];
1998 const UINT_32 MaxBitsUsed
= 4;
1999 ADDR_CHANNEL_SETTING x
[MaxBitsUsed
] = {};
2000 ADDR_CHANNEL_SETTING y
[MaxBitsUsed
] = {};
2002 for (i
= 0; i
< MaxBitsUsed
; i
++)
2004 InitChannel(1, 0, elementBytesLog2
+ i
, &x
[i
]);
2005 InitChannel(1, 1, i
, &y
[i
]);
2008 if (IsStandardSwizzle(rsrcType
, swMode
))
2010 switch (elementBytesLog2
)
2053 ADDR_ASSERT_ALWAYS();
2054 ret
= ADDR_INVALIDPARAMS
;
2058 else if (IsDisplaySwizzle(rsrcType
, swMode
))
2060 switch (elementBytesLog2
)
2103 ADDR_ASSERT_ALWAYS();
2104 ret
= ADDR_INVALIDPARAMS
;
2108 else if (IsRotateSwizzle(swMode
))
2110 switch (elementBytesLog2
)
2147 ADDR_ASSERT_ALWAYS();
2149 ret
= ADDR_INVALIDPARAMS
;
2155 ADDR_ASSERT_ALWAYS();
2156 ret
= ADDR_INVALIDPARAMS
;
2162 Dim2d microBlockDim
= Block256b
[elementBytesLog2
];
2163 ADDR_ASSERT((2u << GetMaxValidChannelIndex(pEquation
->addr
, 8, 0)) ==
2164 (microBlockDim
.w
* (1 << elementBytesLog2
)));
2165 ADDR_ASSERT((2u << GetMaxValidChannelIndex(pEquation
->addr
, 8, 1)) == microBlockDim
.h
);
2172 ****************************************************************************************************
2173 * Gfx9Lib::HwlComputeThinEquation
2176 * Interface function stub of ComputeThinEquation
2180 ****************************************************************************************************
2182 ADDR_E_RETURNCODE
Gfx9Lib::HwlComputeThinEquation(
2183 AddrResourceType rsrcType
,
2184 AddrSwizzleMode swMode
,
2185 UINT_32 elementBytesLog2
,
2186 ADDR_EQUATION
* pEquation
) const
2188 ADDR_E_RETURNCODE ret
= ADDR_OK
;
2190 UINT_32 blockSizeLog2
= GetBlockSizeLog2(swMode
);
2192 UINT_32 maxXorBits
= blockSizeLog2
;
2193 if (IsNonPrtXor(swMode
))
2195 // For non-prt-xor, maybe need to initialize some more bits for xor
2196 // The highest xor bit used in equation will be max the following 3 items:
2197 // 1. m_pipeInterleaveLog2 + 2 * pipeXorBits
2198 // 2. m_pipeInterleaveLog2 + pipeXorBits + 2 * bankXorBits
2201 maxXorBits
= Max(maxXorBits
, m_pipeInterleaveLog2
+ 2 * GetPipeXorBits(blockSizeLog2
));
2202 maxXorBits
= Max(maxXorBits
, m_pipeInterleaveLog2
+
2203 GetPipeXorBits(blockSizeLog2
) +
2204 2 * GetBankXorBits(blockSizeLog2
));
2207 const UINT_32 MaxBitsUsed
= 14;
2208 ADDR_ASSERT((2 * MaxBitsUsed
) >= maxXorBits
);
2209 ADDR_CHANNEL_SETTING x
[MaxBitsUsed
] = {};
2210 ADDR_CHANNEL_SETTING y
[MaxBitsUsed
] = {};
2212 const UINT_32 ExtraXorBits
= 16;
2213 ADDR_ASSERT(ExtraXorBits
>= maxXorBits
- blockSizeLog2
);
2214 ADDR_CHANNEL_SETTING xorExtra
[ExtraXorBits
] = {};
2216 for (UINT_32 i
= 0; i
< MaxBitsUsed
; i
++)
2218 InitChannel(1, 0, elementBytesLog2
+ i
, &x
[i
]);
2219 InitChannel(1, 1, i
, &y
[i
]);
2222 ADDR_CHANNEL_SETTING
* pixelBit
= pEquation
->addr
;
2224 for (UINT_32 i
= 0; i
< elementBytesLog2
; i
++)
2226 InitChannel(1, 0 , i
, &pixelBit
[i
]);
2231 UINT_32 lowBits
= 0;
2233 if (IsZOrderSwizzle(swMode
))
2235 if (elementBytesLog2
<= 3)
2237 for (UINT_32 i
= elementBytesLog2
; i
< 6; i
++)
2239 pixelBit
[i
] = (((i
- elementBytesLog2
) & 1) == 0) ? x
[xIdx
++] : y
[yIdx
++];
2246 ret
= ADDR_INVALIDPARAMS
;
2251 ret
= HwlComputeBlock256Equation(rsrcType
, swMode
, elementBytesLog2
, pEquation
);
2254 Dim2d microBlockDim
= Block256b
[elementBytesLog2
];
2255 xIdx
= Log2(microBlockDim
.w
);
2256 yIdx
= Log2(microBlockDim
.h
);
2263 for (UINT_32 i
= lowBits
; i
< blockSizeLog2
; i
++)
2265 pixelBit
[i
] = ((i
& 1) == 0) ? y
[yIdx
++] : x
[xIdx
++];
2268 for (UINT_32 i
= blockSizeLog2
; i
< maxXorBits
; i
++)
2270 xorExtra
[i
- blockSizeLog2
] = ((i
& 1) == 0) ? y
[yIdx
++] : x
[xIdx
++];
2274 if ((ret
== ADDR_OK
) && IsXor(swMode
))
2277 UINT_32 pipeStart
= m_pipeInterleaveLog2
;
2278 UINT_32 pipeXorBits
= GetPipeXorBits(blockSizeLog2
);
2279 for (UINT_32 i
= 0; i
< pipeXorBits
; i
++)
2281 UINT_32 xor1BitPos
= pipeStart
+ 2 * pipeXorBits
- 1 - i
;
2282 ADDR_CHANNEL_SETTING
* pXor1Src
=
2283 (xor1BitPos
< blockSizeLog2
) ?
2284 &pEquation
->addr
[xor1BitPos
] : &xorExtra
[xor1BitPos
- blockSizeLog2
];
2286 InitChannel(&pEquation
->xor1
[pipeStart
+ i
], pXor1Src
);
2289 UINT_32 bankStart
= pipeStart
+ pipeXorBits
;
2290 UINT_32 bankXorBits
= GetBankXorBits(blockSizeLog2
);
2291 for (UINT_32 i
= 0; i
< bankXorBits
; i
++)
2293 UINT_32 xor1BitPos
= bankStart
+ 2 * bankXorBits
- 1 - i
;
2294 ADDR_CHANNEL_SETTING
* pXor1Src
=
2295 (xor1BitPos
< blockSizeLog2
) ?
2296 &pEquation
->addr
[xor1BitPos
] : &xorExtra
[xor1BitPos
- blockSizeLog2
];
2298 InitChannel(&pEquation
->xor1
[pipeStart
+ i
], pXor1Src
);
2301 pEquation
->numBits
= blockSizeLog2
;
2304 if ((ret
== ADDR_OK
) && IsTex3d(rsrcType
))
2306 pEquation
->stackedDepthSlices
= TRUE
;
2313 ****************************************************************************************************
2314 * Gfx9Lib::HwlComputeThickEquation
2317 * Interface function stub of ComputeThickEquation
2321 ****************************************************************************************************
2323 ADDR_E_RETURNCODE
Gfx9Lib::HwlComputeThickEquation(
2324 AddrResourceType rsrcType
,
2325 AddrSwizzleMode swMode
,
2326 UINT_32 elementBytesLog2
,
2327 ADDR_EQUATION
* pEquation
) const
2329 ADDR_E_RETURNCODE ret
= ADDR_OK
;
2331 ADDR_ASSERT(IsTex3d(rsrcType
));
2333 UINT_32 blockSizeLog2
= GetBlockSizeLog2(swMode
);
2335 UINT_32 maxXorBits
= blockSizeLog2
;
2336 if (IsNonPrtXor(swMode
))
2338 // For non-prt-xor, maybe need to initialize some more bits for xor
2339 // The highest xor bit used in equation will be max the following 3:
2340 // 1. m_pipeInterleaveLog2 + 3 * pipeXorBits
2341 // 2. m_pipeInterleaveLog2 + pipeXorBits + 3 * bankXorBits
2344 maxXorBits
= Max(maxXorBits
, m_pipeInterleaveLog2
+ 3 * GetPipeXorBits(blockSizeLog2
));
2345 maxXorBits
= Max(maxXorBits
, m_pipeInterleaveLog2
+
2346 GetPipeXorBits(blockSizeLog2
) +
2347 3 * GetBankXorBits(blockSizeLog2
));
2350 for (UINT_32 i
= 0; i
< elementBytesLog2
; i
++)
2352 InitChannel(1, 0 , i
, &pEquation
->addr
[i
]);
2355 ADDR_CHANNEL_SETTING
* pixelBit
= &pEquation
->addr
[elementBytesLog2
];
2357 const UINT_32 MaxBitsUsed
= 12;
2358 ADDR_ASSERT((3 * MaxBitsUsed
) >= maxXorBits
);
2359 ADDR_CHANNEL_SETTING x
[MaxBitsUsed
] = {};
2360 ADDR_CHANNEL_SETTING y
[MaxBitsUsed
] = {};
2361 ADDR_CHANNEL_SETTING z
[MaxBitsUsed
] = {};
2363 const UINT_32 ExtraXorBits
= 24;
2364 ADDR_ASSERT(ExtraXorBits
>= maxXorBits
- blockSizeLog2
);
2365 ADDR_CHANNEL_SETTING xorExtra
[ExtraXorBits
] = {};
2367 for (UINT_32 i
= 0; i
< MaxBitsUsed
; i
++)
2369 InitChannel(1, 0, elementBytesLog2
+ i
, &x
[i
]);
2370 InitChannel(1, 1, i
, &y
[i
]);
2371 InitChannel(1, 2, i
, &z
[i
]);
2374 if (IsZOrderSwizzle(swMode
))
2376 switch (elementBytesLog2
)
2429 ADDR_ASSERT_ALWAYS();
2430 ret
= ADDR_INVALIDPARAMS
;
2434 else if (IsStandardSwizzle(rsrcType
, swMode
))
2436 switch (elementBytesLog2
)
2489 ADDR_ASSERT_ALWAYS();
2490 ret
= ADDR_INVALIDPARAMS
;
2496 ADDR_ASSERT_ALWAYS();
2497 ret
= ADDR_INVALIDPARAMS
;
2502 Dim3d microBlockDim
= Block1kb
[elementBytesLog2
];
2503 UINT_32 xIdx
= Log2(microBlockDim
.w
);
2504 UINT_32 yIdx
= Log2(microBlockDim
.h
);
2505 UINT_32 zIdx
= Log2(microBlockDim
.d
);
2507 pixelBit
= pEquation
->addr
;
2509 static const UINT_32 lowBits
= 10;
2510 ADDR_ASSERT(pEquation
->addr
[lowBits
- 1].valid
== 1);
2511 ADDR_ASSERT(pEquation
->addr
[lowBits
].valid
== 0);
2513 for (UINT_32 i
= lowBits
; i
< blockSizeLog2
; i
++)
2515 if (((i
- lowBits
) % 3) == 0)
2517 pixelBit
[i
] = x
[xIdx
++];
2519 else if (((i
- lowBits
) % 3) == 1)
2521 pixelBit
[i
] = z
[zIdx
++];
2525 pixelBit
[i
] = y
[yIdx
++];
2529 for (UINT_32 i
= blockSizeLog2
; i
< maxXorBits
; i
++)
2531 if (((i
- lowBits
) % 3) == 0)
2533 xorExtra
[i
- blockSizeLog2
] = x
[xIdx
++];
2535 else if (((i
- lowBits
) % 3) == 1)
2537 xorExtra
[i
- blockSizeLog2
] = z
[zIdx
++];
2541 xorExtra
[i
- blockSizeLog2
] = y
[yIdx
++];
2546 if ((ret
== ADDR_OK
) && IsXor(swMode
))
2549 UINT_32 pipeStart
= m_pipeInterleaveLog2
;
2550 UINT_32 pipeXorBits
= GetPipeXorBits(blockSizeLog2
);
2551 for (UINT_32 i
= 0; i
< pipeXorBits
; i
++)
2553 UINT_32 xor1BitPos
= pipeStart
+ (3 * pipeXorBits
) - 1 - (2 * i
);
2554 ADDR_CHANNEL_SETTING
* pXor1Src
=
2555 (xor1BitPos
< blockSizeLog2
) ?
2556 &pEquation
->addr
[xor1BitPos
] : &xorExtra
[xor1BitPos
- blockSizeLog2
];
2558 InitChannel(&pEquation
->xor1
[pipeStart
+ i
], pXor1Src
);
2560 UINT_32 xor2BitPos
= pipeStart
+ (3 * pipeXorBits
) - 2 - (2 * i
);
2561 ADDR_CHANNEL_SETTING
* pXor2Src
=
2562 (xor2BitPos
< blockSizeLog2
) ?
2563 &pEquation
->addr
[xor2BitPos
] : &xorExtra
[xor2BitPos
- blockSizeLog2
];
2565 InitChannel(&pEquation
->xor2
[pipeStart
+ i
], pXor2Src
);
2568 UINT_32 bankStart
= pipeStart
+ pipeXorBits
;
2569 UINT_32 bankXorBits
= GetBankXorBits(blockSizeLog2
);
2570 for (UINT_32 i
= 0; i
< bankXorBits
; i
++)
2572 UINT_32 xor1BitPos
= bankStart
+ (3 * bankXorBits
) - 1 - (2 * i
);
2573 ADDR_CHANNEL_SETTING
* pXor1Src
=
2574 (xor1BitPos
< blockSizeLog2
) ?
2575 &pEquation
->addr
[xor1BitPos
] : &xorExtra
[xor1BitPos
- blockSizeLog2
];
2577 InitChannel(&pEquation
->xor1
[bankStart
+ i
], pXor1Src
);
2579 UINT_32 xor2BitPos
= bankStart
+ (3 * bankXorBits
) - 2 - (2 * i
);
2580 ADDR_CHANNEL_SETTING
* pXor2Src
=
2581 (xor2BitPos
< blockSizeLog2
) ?
2582 &pEquation
->addr
[xor2BitPos
] : &xorExtra
[xor2BitPos
- blockSizeLog2
];
2584 InitChannel(&pEquation
->xor2
[bankStart
+ i
], pXor2Src
);
2587 pEquation
->numBits
= blockSizeLog2
;
2594 ****************************************************************************************************
2595 * Gfx9Lib::HwlIsValidDisplaySwizzleMode
2598 * Check if a swizzle mode is supported by display engine
2601 * TRUE is swizzle mode is supported by display engine
2602 ****************************************************************************************************
2604 BOOL_32
Gfx9Lib::HwlIsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
) const
2606 BOOL_32 support
= FALSE
;
2608 //const AddrResourceType resourceType = pIn->resourceType;
2609 const AddrSwizzleMode swizzleMode
= pIn
->swizzleMode
;
2611 if (m_settings
.isDce12
)
2613 switch (swizzleMode
)
2615 case ADDR_SW_256B_D
:
2616 case ADDR_SW_256B_R
:
2617 support
= (pIn
->bpp
== 32);
2620 case ADDR_SW_LINEAR
:
2623 case ADDR_SW_64KB_D
:
2624 case ADDR_SW_64KB_R
:
2627 case ADDR_SW_4KB_D_X
:
2628 case ADDR_SW_4KB_R_X
:
2629 case ADDR_SW_64KB_D_X
:
2630 case ADDR_SW_64KB_R_X
:
2631 case ADDR_SW_VAR_D_X
:
2632 case ADDR_SW_VAR_R_X
:
2633 support
= (pIn
->bpp
<= 64);
2642 ADDR_NOT_IMPLEMENTED();