2 * Copyright © 2007-2019 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 ************************************************************************************************************************
29 * @file gfx10addrlib.cpp
30 * @brief Contain the implementation for the Gfx10Lib class.
31 ************************************************************************************************************************
34 #include "gfx10addrlib.h"
35 #include "gfx10_gb_reg.h"
36 #include "gfx10SwizzlePattern.h"
38 #include "amdgpu_asic_addr.h"
40 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
41 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
46 ************************************************************************************************************************
50 * Creates an Gfx10Lib object.
53 * Returns an Gfx10Lib object pointer.
54 ************************************************************************************************************************
56 Addr::Lib
* Gfx10HwlInit(const Client
* pClient
)
58 return V2::Gfx10Lib::CreateObj(pClient
);
64 ////////////////////////////////////////////////////////////////////////////////////////////////////
65 // Static Const Member
66 ////////////////////////////////////////////////////////////////////////////////////////////////////
68 const SwizzleModeFlags
Gfx10Lib::SwizzleModeTable
[ADDR_SW_MAX_TYPE
] =
69 {//Linear 256B 4KB 64KB Var Z Std Disp Rot XOR T RtOpt
70 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_SW_LINEAR
71 {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_256B_S
72 {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_256B_D
73 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
75 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
76 {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_4KB_S
77 {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_4KB_D
78 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
80 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
81 {0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_64KB_S
82 {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_64KB_D
83 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
85 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
86 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
87 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
88 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
90 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
91 {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0}, // ADDR_SW_64KB_S_T
92 {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0}, // ADDR_SW_64KB_D_T
93 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
95 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
96 {0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0}, // ADDR_SW_4KB_S_X
97 {0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0}, // ADDR_SW_4KB_D_X
98 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
100 {0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0}, // ADDR_SW_64KB_Z_X
101 {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, // ADDR_SW_64KB_S_X
102 {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0}, // ADDR_SW_64KB_D_X
103 {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1}, // ADDR_SW_64KB_R_X
105 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
106 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
107 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
108 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
109 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_SW_LINEAR_GENERAL
112 const Dim3d
Gfx10Lib::Block256_3d
[] = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}};
114 const Dim3d
Gfx10Lib::Block64K_3d
[] = {{64, 32, 32}, {32 , 32, 32}, {32, 32, 16}, {32, 16, 16}, {16, 16, 16}};
115 const Dim3d
Gfx10Lib::Block4K_3d
[] = {{16, 16, 16}, {8, 16, 16}, {8, 16, 8}, {8, 8, 8}, {4, 8, 8}};
117 const Dim2d
Gfx10Lib::Block64K_2d
[] = {{256, 256}, {256 , 128}, {128, 128}, {128, 64}, {64, 64}};
118 const Dim2d
Gfx10Lib::Block4K_2d
[] = {{64, 64}, {64, 32}, {32, 32}, {32, 16}, {16, 16}};
120 const Dim3d
Gfx10Lib::Block64K_Log2_3d
[] = {{6, 5, 5}, {5, 5, 5}, {5, 5, 4}, {5, 4, 4}, {4, 4, 4}};
121 const Dim3d
Gfx10Lib::Block4K_Log2_3d
[] = {{4, 4, 4}, {3, 4, 4}, {3, 4, 3}, {3, 3, 3}, {2, 3, 3}};
123 const Dim2d
Gfx10Lib::Block64K_Log2_2d
[] = {{8, 8}, {8, 7}, {7, 7}, {7, 6}, {6, 6}};
124 const Dim2d
Gfx10Lib::Block4K_Log2_2d
[] = {{6, 6}, {6, 5}, {5, 5}, {5, 4}, {4, 4}};
127 ************************************************************************************************************************
133 ************************************************************************************************************************
135 Gfx10Lib::Gfx10Lib(const Client
* pClient
)
140 m_class
= AI_ADDRLIB
;
141 memset(&m_settings
, 0, sizeof(m_settings
));
142 memcpy(m_swizzleModeTable
, SwizzleModeTable
, sizeof(SwizzleModeTable
));
146 ************************************************************************************************************************
147 * Gfx10Lib::~Gfx10Lib
151 ************************************************************************************************************************
153 Gfx10Lib::~Gfx10Lib()
158 ************************************************************************************************************************
159 * Gfx10Lib::HwlComputeHtileInfo
162 * Interface function stub of AddrComputeHtilenfo
166 ************************************************************************************************************************
168 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeHtileInfo(
169 const ADDR2_COMPUTE_HTILE_INFO_INPUT
* pIn
, ///< [in] input structure
170 ADDR2_COMPUTE_HTILE_INFO_OUTPUT
* pOut
///< [out] output structure
173 ADDR_E_RETURNCODE ret
= ADDR_OK
;
175 if ((pIn
->swizzleMode
!= ADDR_SW_64KB_Z_X
) ||
176 (pIn
->hTileFlags
.pipeAligned
!= TRUE
))
178 ret
= ADDR_INVALIDPARAMS
;
183 const UINT_32 metaBlkSize
= GetMetaBlkSize(Gfx10DataDepthStencil
,
191 pOut
->pitch
= PowTwoAlign(pIn
->unalignedWidth
, metaBlk
.w
);
192 pOut
->height
= PowTwoAlign(pIn
->unalignedHeight
, metaBlk
.h
);
193 pOut
->baseAlign
= Max(metaBlkSize
, 1u << (m_pipesLog2
+ 11u));
194 pOut
->metaBlkWidth
= metaBlk
.w
;
195 pOut
->metaBlkHeight
= metaBlk
.h
;
197 if (pIn
->numMipLevels
> 1)
199 ADDR_ASSERT(pIn
->firstMipIdInTail
<= pIn
->numMipLevels
);
201 UINT_32 offset
= (pIn
->firstMipIdInTail
== pIn
->numMipLevels
) ? 0 : metaBlkSize
;
203 for (INT_32 i
= static_cast<INT_32
>(pIn
->firstMipIdInTail
) - 1; i
>=0; i
--)
205 UINT_32 mipWidth
, mipHeight
;
207 GetMipSize(pIn
->unalignedWidth
, pIn
->unalignedHeight
, 1, i
, &mipWidth
, &mipHeight
);
209 mipWidth
= PowTwoAlign(mipWidth
, metaBlk
.w
);
210 mipHeight
= PowTwoAlign(mipHeight
, metaBlk
.h
);
212 const UINT_32 pitchInM
= mipWidth
/ metaBlk
.w
;
213 const UINT_32 heightInM
= mipHeight
/ metaBlk
.h
;
214 const UINT_32 mipSliceSize
= pitchInM
* heightInM
* metaBlkSize
;
216 if (pOut
->pMipInfo
!= NULL
)
218 pOut
->pMipInfo
[i
].inMiptail
= FALSE
;
219 pOut
->pMipInfo
[i
].offset
= offset
;
220 pOut
->pMipInfo
[i
].sliceSize
= mipSliceSize
;
223 offset
+= mipSliceSize
;
226 pOut
->sliceSize
= offset
;
227 pOut
->metaBlkNumPerSlice
= offset
/ metaBlkSize
;
228 pOut
->htileBytes
= pOut
->sliceSize
* pIn
->numSlices
;
230 if (pOut
->pMipInfo
!= NULL
)
232 for (UINT_32 i
= pIn
->firstMipIdInTail
; i
< pIn
->numMipLevels
; i
++)
234 pOut
->pMipInfo
[i
].inMiptail
= TRUE
;
235 pOut
->pMipInfo
[i
].offset
= 0;
236 pOut
->pMipInfo
[i
].sliceSize
= 0;
239 if (pIn
->firstMipIdInTail
!= pIn
->numMipLevels
)
241 pOut
->pMipInfo
[pIn
->firstMipIdInTail
].sliceSize
= metaBlkSize
;
247 const UINT_32 pitchInM
= pOut
->pitch
/ metaBlk
.w
;
248 const UINT_32 heightInM
= pOut
->height
/ metaBlk
.h
;
250 pOut
->metaBlkNumPerSlice
= pitchInM
* heightInM
;
251 pOut
->sliceSize
= pOut
->metaBlkNumPerSlice
* metaBlkSize
;
252 pOut
->htileBytes
= pOut
->sliceSize
* pIn
->numSlices
;
254 if (pOut
->pMipInfo
!= NULL
)
256 pOut
->pMipInfo
[0].inMiptail
= FALSE
;
257 pOut
->pMipInfo
[0].offset
= 0;
258 pOut
->pMipInfo
[0].sliceSize
= pOut
->sliceSize
;
267 ************************************************************************************************************************
268 * Gfx10Lib::HwlComputeCmaskInfo
271 * Interface function stub of AddrComputeCmaskInfo
275 ************************************************************************************************************************
277 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeCmaskInfo(
278 const ADDR2_COMPUTE_CMASK_INFO_INPUT
* pIn
, ///< [in] input structure
279 ADDR2_COMPUTE_CMASK_INFO_OUTPUT
* pOut
///< [out] output structure
282 ADDR_E_RETURNCODE ret
= ADDR_OK
;
284 if ((pIn
->resourceType
!= ADDR_RSRC_TEX_2D
) ||
285 (pIn
->cMaskFlags
.pipeAligned
!= TRUE
))
287 ret
= ADDR_INVALIDPARAMS
;
292 const UINT_32 metaBlkSize
= GetMetaBlkSize(Gfx10DataFmask
,
300 pOut
->pitch
= PowTwoAlign(pIn
->unalignedWidth
, metaBlk
.w
);
301 pOut
->height
= PowTwoAlign(pIn
->unalignedHeight
, metaBlk
.h
);
302 pOut
->baseAlign
= metaBlkSize
;
303 pOut
->metaBlkWidth
= metaBlk
.w
;
304 pOut
->metaBlkHeight
= metaBlk
.h
;
306 if (pIn
->numMipLevels
> 1)
308 ADDR_ASSERT(pIn
->firstMipIdInTail
<= pIn
->numMipLevels
);
310 UINT_32 metaBlkPerSlice
= (pIn
->firstMipIdInTail
== pIn
->numMipLevels
) ? 0 : 1;
312 for (INT_32 i
= static_cast<INT_32
>(pIn
->firstMipIdInTail
) - 1; i
>= 0; i
--)
314 UINT_32 mipWidth
, mipHeight
;
316 GetMipSize(pIn
->unalignedWidth
, pIn
->unalignedHeight
, 1, i
, &mipWidth
, &mipHeight
);
318 mipWidth
= PowTwoAlign(mipWidth
, metaBlk
.w
);
319 mipHeight
= PowTwoAlign(mipHeight
, metaBlk
.h
);
321 const UINT_32 pitchInM
= mipWidth
/ metaBlk
.w
;
322 const UINT_32 heightInM
= mipHeight
/ metaBlk
.h
;
324 if (pOut
->pMipInfo
!= NULL
)
326 pOut
->pMipInfo
[i
].inMiptail
= FALSE
;
327 pOut
->pMipInfo
[i
].offset
= metaBlkPerSlice
* metaBlkSize
;
328 pOut
->pMipInfo
[i
].sliceSize
= pitchInM
* heightInM
* metaBlkSize
;
331 metaBlkPerSlice
+= pitchInM
* heightInM
;
334 pOut
->metaBlkNumPerSlice
= metaBlkPerSlice
;
336 if (pOut
->pMipInfo
!= NULL
)
338 for (UINT_32 i
= pIn
->firstMipIdInTail
; i
< pIn
->numMipLevels
; i
++)
340 pOut
->pMipInfo
[i
].inMiptail
= TRUE
;
341 pOut
->pMipInfo
[i
].offset
= 0;
342 pOut
->pMipInfo
[i
].sliceSize
= 0;
345 if (pIn
->firstMipIdInTail
!= pIn
->numMipLevels
)
347 pOut
->pMipInfo
[pIn
->firstMipIdInTail
].sliceSize
= metaBlkSize
;
353 const UINT_32 pitchInM
= pOut
->pitch
/ metaBlk
.w
;
354 const UINT_32 heightInM
= pOut
->height
/ metaBlk
.h
;
356 pOut
->metaBlkNumPerSlice
= pitchInM
* heightInM
;
358 if (pOut
->pMipInfo
!= NULL
)
360 pOut
->pMipInfo
[0].inMiptail
= FALSE
;
361 pOut
->pMipInfo
[0].offset
= 0;
362 pOut
->pMipInfo
[0].sliceSize
= pOut
->metaBlkNumPerSlice
* metaBlkSize
;
366 pOut
->sliceSize
= pOut
->metaBlkNumPerSlice
* metaBlkSize
;
367 pOut
->cmaskBytes
= pOut
->sliceSize
* pIn
->numSlices
;
374 ************************************************************************************************************************
375 * Gfx10Lib::HwlComputeDccInfo
378 * Interface function to compute DCC key info
382 ************************************************************************************************************************
384 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeDccInfo(
385 const ADDR2_COMPUTE_DCCINFO_INPUT
* pIn
, ///< [in] input structure
386 ADDR2_COMPUTE_DCCINFO_OUTPUT
* pOut
///< [out] output structure
389 ADDR_E_RETURNCODE ret
= ADDR_OK
;
391 if (pIn
->swizzleMode
!= ADDR_SW_64KB_Z_X
&& pIn
->swizzleMode
!= ADDR_SW_64KB_R_X
)
393 // Hardware does not support DCC for this swizzle mode.
394 ret
= ADDR_INVALIDPARAMS
;
396 else if (m_settings
.dccUnsup3DSwDis
&& IsTex3d(pIn
->resourceType
) && IsDisplaySwizzle(pIn
->swizzleMode
))
398 // DCC is not supported on 3D Display surfaces for GFX10.0 and GFX10.1
399 ret
= ADDR_INVALIDPARAMS
;
403 // only SW_*_R_X surfaces may be DCC compressed when attached to the CB
404 ADDR_ASSERT(IsRtOptSwizzle(pIn
->swizzleMode
));
407 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
408 const UINT_32 numFragLog2
= Log2(pIn
->numFrags
);
409 const UINT_32 metaBlkSize
= GetMetaBlkSize(Gfx10DataColor
,
414 pIn
->dccKeyFlags
.pipeAligned
,
416 const BOOL_32 isThick
= IsThick(pIn
->resourceType
, pIn
->swizzleMode
);
418 pOut
->compressBlkWidth
= isThick
? Block256_3d
[elemLog2
].w
: Block256_2d
[elemLog2
].w
;
419 pOut
->compressBlkHeight
= isThick
? Block256_3d
[elemLog2
].h
: Block256_2d
[elemLog2
].h
;
420 pOut
->compressBlkDepth
= isThick
? Block256_3d
[elemLog2
].d
: 1;
422 pOut
->dccRamBaseAlign
= metaBlkSize
;
423 pOut
->metaBlkWidth
= metaBlk
.w
;
424 pOut
->metaBlkHeight
= metaBlk
.h
;
425 pOut
->metaBlkDepth
= metaBlk
.d
;
427 pOut
->pitch
= PowTwoAlign(pIn
->unalignedWidth
, metaBlk
.w
);
428 pOut
->height
= PowTwoAlign(pIn
->unalignedHeight
, metaBlk
.h
);
429 pOut
->depth
= PowTwoAlign(pIn
->numSlices
, metaBlk
.d
);
431 if (pIn
->numMipLevels
> 1)
433 ADDR_ASSERT(pIn
->firstMipIdInTail
<= pIn
->numMipLevels
);
435 UINT_32 offset
= (pIn
->firstMipIdInTail
== pIn
->numMipLevels
) ? 0 : metaBlkSize
;
437 for (INT_32 i
= static_cast<INT_32
>(pIn
->firstMipIdInTail
) - 1; i
>= 0; i
--)
439 UINT_32 mipWidth
, mipHeight
;
441 GetMipSize(pIn
->unalignedWidth
, pIn
->unalignedHeight
, 1, i
, &mipWidth
, &mipHeight
);
443 mipWidth
= PowTwoAlign(mipWidth
, metaBlk
.w
);
444 mipHeight
= PowTwoAlign(mipHeight
, metaBlk
.h
);
446 const UINT_32 pitchInM
= mipWidth
/ metaBlk
.w
;
447 const UINT_32 heightInM
= mipHeight
/ metaBlk
.h
;
448 const UINT_32 mipSliceSize
= pitchInM
* heightInM
* metaBlkSize
;
450 if (pOut
->pMipInfo
!= NULL
)
452 pOut
->pMipInfo
[i
].inMiptail
= FALSE
;
453 pOut
->pMipInfo
[i
].offset
= offset
;
454 pOut
->pMipInfo
[i
].sliceSize
= mipSliceSize
;
457 offset
+= mipSliceSize
;
460 pOut
->dccRamSliceSize
= offset
;
461 pOut
->metaBlkNumPerSlice
= offset
/ metaBlkSize
;
462 pOut
->dccRamSize
= pOut
->dccRamSliceSize
* (pOut
->depth
/ metaBlk
.d
);
464 if (pOut
->pMipInfo
!= NULL
)
466 for (UINT_32 i
= pIn
->firstMipIdInTail
; i
< pIn
->numMipLevels
; i
++)
468 pOut
->pMipInfo
[i
].inMiptail
= TRUE
;
469 pOut
->pMipInfo
[i
].offset
= 0;
470 pOut
->pMipInfo
[i
].sliceSize
= 0;
473 if (pIn
->firstMipIdInTail
!= pIn
->numMipLevels
)
475 pOut
->pMipInfo
[pIn
->firstMipIdInTail
].sliceSize
= metaBlkSize
;
481 const UINT_32 pitchInM
= pOut
->pitch
/ metaBlk
.w
;
482 const UINT_32 heightInM
= pOut
->height
/ metaBlk
.h
;
484 pOut
->metaBlkNumPerSlice
= pitchInM
* heightInM
;
485 pOut
->dccRamSliceSize
= pOut
->metaBlkNumPerSlice
* metaBlkSize
;
486 pOut
->dccRamSize
= pOut
->dccRamSliceSize
* (pOut
->depth
/ metaBlk
.d
);
488 if (pOut
->pMipInfo
!= NULL
)
490 pOut
->pMipInfo
[0].inMiptail
= FALSE
;
491 pOut
->pMipInfo
[0].offset
= 0;
492 pOut
->pMipInfo
[0].sliceSize
= pOut
->dccRamSliceSize
;
501 ************************************************************************************************************************
502 * Gfx10Lib::HwlComputeCmaskAddrFromCoord
505 * Interface function stub of AddrComputeCmaskAddrFromCoord
509 ************************************************************************************************************************
511 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeCmaskAddrFromCoord(
512 const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
513 ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
) ///< [out] output structure
515 ADDR2_COMPUTE_CMASK_INFO_INPUT input
= {0};
516 input
.size
= sizeof(input
);
517 input
.cMaskFlags
= pIn
->cMaskFlags
;
518 input
.colorFlags
= pIn
->colorFlags
;
519 input
.unalignedWidth
= Max(pIn
->unalignedWidth
, 1u);
520 input
.unalignedHeight
= Max(pIn
->unalignedHeight
, 1u);
521 input
.numSlices
= Max(pIn
->numSlices
, 1u);
522 input
.swizzleMode
= pIn
->swizzleMode
;
523 input
.resourceType
= pIn
->resourceType
;
525 ADDR2_COMPUTE_CMASK_INFO_OUTPUT output
= {0};
526 output
.size
= sizeof(output
);
528 ADDR_E_RETURNCODE returnCode
= ComputeCmaskInfo(&input
, &output
);
530 if (returnCode
== ADDR_OK
)
532 const UINT_32 fmaskBpp
= GetFmaskBpp(pIn
->numSamples
, pIn
->numFrags
);
533 const UINT_32 fmaskElemLog2
= Log2(fmaskBpp
>> 3);
534 const UINT_32 numPipeLog2
= m_pipesLog2
;
535 const UINT_32 pipeMask
= (1 << numPipeLog2
) - 1;
536 const UINT_32 fmaskBppType
= 4;
537 const UINT_32 numPipeType
= 8;
538 const UINT_32 index
= ((m_pipeInterleaveLog2
- 8) * (fmaskBppType
* numPipeType
)) +
539 ((numPipeLog2
+ 1) * fmaskBppType
) +
542 const UINT_64
* pPattern
= CMASK_64K
[index
];
543 const UINT_32 blkSizeLog2
= Log2(output
.metaBlkWidth
) + Log2(output
.metaBlkHeight
) - 7;
544 const UINT_32 blkMask
= (1 << blkSizeLog2
) - 1;
545 const UINT_32 blkOffset
= ComputeOffsetFromSwizzlePattern(pPattern
,
546 blkSizeLog2
+ 1, // +1 for nibble offset
551 const UINT_32 xb
= pIn
->x
/ output
.metaBlkWidth
;
552 const UINT_32 yb
= pIn
->y
/ output
.metaBlkHeight
;
553 const UINT_32 pb
= output
.pitch
/ output
.metaBlkWidth
;
554 const UINT_32 blkIndex
= (yb
* pb
) + xb
;
555 const UINT_32 pipeXor
= ((pIn
->pipeXor
& pipeMask
) << m_pipeInterleaveLog2
) & blkMask
;
557 pOut
->addr
= (output
.sliceSize
* pIn
->slice
) +
558 (blkIndex
* (1 << blkSizeLog2
)) +
559 ((blkOffset
>> 1) ^ pipeXor
);
560 pOut
->bitPosition
= (blkOffset
& 1) << 2;
567 ************************************************************************************************************************
568 * Gfx10Lib::HwlComputeHtileAddrFromCoord
571 * Interface function stub of AddrComputeHtileAddrFromCoord
575 ************************************************************************************************************************
577 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeHtileAddrFromCoord(
578 const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
579 ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
) ///< [out] output structure
581 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
583 if (pIn
->numMipLevels
> 1)
585 returnCode
= ADDR_NOTIMPLEMENTED
;
589 ADDR2_COMPUTE_HTILE_INFO_INPUT input
= {0};
590 input
.size
= sizeof(input
);
591 input
.hTileFlags
= pIn
->hTileFlags
;
592 input
.depthFlags
= pIn
->depthflags
;
593 input
.swizzleMode
= pIn
->swizzleMode
;
594 input
.unalignedWidth
= Max(pIn
->unalignedWidth
, 1u);
595 input
.unalignedHeight
= Max(pIn
->unalignedHeight
, 1u);
596 input
.numSlices
= Max(pIn
->numSlices
, 1u);
597 input
.numMipLevels
= 1;
599 ADDR2_COMPUTE_HTILE_INFO_OUTPUT output
= {0};
600 output
.size
= sizeof(output
);
602 returnCode
= ComputeHtileInfo(&input
, &output
);
604 if (returnCode
== ADDR_OK
)
606 const UINT_32 numSampleLog2
= Log2(pIn
->numSamples
);
607 const UINT_32 pipeMask
= (1 << m_pipesLog2
) - 1;
608 const UINT_32 index
= m_htileBaseIndex
+ numSampleLog2
;
609 const UINT_64
* pPattern
= HTILE_64K
[index
];
610 const UINT_32 blkSizeLog2
= Log2(output
.metaBlkWidth
) + Log2(output
.metaBlkHeight
) - 4;
611 const UINT_32 blkMask
= (1 << blkSizeLog2
) - 1;
612 const UINT_32 blkOffset
= ComputeOffsetFromSwizzlePattern(pPattern
,
613 blkSizeLog2
+ 1, // +1 for nibble offset
618 const UINT_32 xb
= pIn
->x
/ output
.metaBlkWidth
;
619 const UINT_32 yb
= pIn
->y
/ output
.metaBlkHeight
;
620 const UINT_32 pb
= output
.pitch
/ output
.metaBlkWidth
;
621 const UINT_32 blkIndex
= (yb
* pb
) + xb
;
622 const UINT_32 pipeXor
= ((pIn
->pipeXor
& pipeMask
) << m_pipeInterleaveLog2
) & blkMask
;
624 pOut
->addr
= (static_cast<UINT_64
>(output
.sliceSize
) * pIn
->slice
) +
625 (blkIndex
* (1 << blkSizeLog2
)) +
626 ((blkOffset
>> 1) ^ pipeXor
);
634 ************************************************************************************************************************
635 * Gfx10Lib::HwlComputeHtileCoordFromAddr
638 * Interface function stub of AddrComputeHtileCoordFromAddr
642 ************************************************************************************************************************
644 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeHtileCoordFromAddr(
645 const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
646 ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
* pOut
) ///< [out] output structure
648 ADDR_NOT_IMPLEMENTED();
654 ************************************************************************************************************************
655 * Gfx10Lib::HwlComputeDccAddrFromCoord
658 * Interface function stub of AddrComputeDccAddrFromCoord
662 ************************************************************************************************************************
664 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeDccAddrFromCoord(
665 const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
666 ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT
* pOut
) ///< [out] output structure
668 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
670 if ((pIn
->resourceType
!= ADDR_RSRC_TEX_2D
) ||
671 (pIn
->swizzleMode
!= ADDR_SW_64KB_R_X
) ||
672 (pIn
->dccKeyFlags
.linear
== TRUE
) ||
673 (pIn
->numFrags
> 1) ||
674 (pIn
->numMipLevels
> 1) ||
677 returnCode
= ADDR_NOTSUPPORTED
;
681 ADDR2_COMPUTE_DCCINFO_INPUT input
= {0};
682 input
.size
= sizeof(input
);
683 input
.dccKeyFlags
= pIn
->dccKeyFlags
;
684 input
.colorFlags
= pIn
->colorFlags
;
685 input
.swizzleMode
= pIn
->swizzleMode
;
686 input
.resourceType
= pIn
->resourceType
;
687 input
.bpp
= pIn
->bpp
;
688 input
.unalignedWidth
= Max(pIn
->unalignedWidth
, 1u);
689 input
.unalignedHeight
= Max(pIn
->unalignedHeight
, 1u);
690 input
.numSlices
= Max(pIn
->numSlices
, 1u);
691 input
.numFrags
= Max(pIn
->numFrags
, 1u);
692 input
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
694 ADDR2_COMPUTE_DCCINFO_OUTPUT output
= {0};
695 output
.size
= sizeof(output
);
697 returnCode
= ComputeDccInfo(&input
, &output
);
699 if (returnCode
== ADDR_OK
)
701 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
702 const UINT_32 numPipeLog2
= m_pipesLog2
;
703 const UINT_32 pipeMask
= (1 << numPipeLog2
) - 1;
704 const UINT_32 alignPipeType
= 7;
705 const UINT_32 unalignPipeType
= 3;
706 const UINT_32 numPipeType
= alignPipeType
+ unalignPipeType
;
707 UINT_32 index
= ((m_pipeInterleaveLog2
- 8) * (MaxNumOfBpp
* numPipeType
)) + elemLog2
;
709 if (pIn
->dccKeyFlags
.pipeAligned
)
711 index
+= (numPipeLog2
+ unalignPipeType
) * MaxNumOfBpp
;
715 index
+= Min(numPipeLog2
, 2u) * MaxNumOfBpp
;
718 const UINT_64
* pPattern
= DCC_64K_R_X
[index
];
719 const UINT_32 blkSizeLog2
= Log2(output
.metaBlkWidth
) + Log2(output
.metaBlkHeight
) + elemLog2
- 8;
720 const UINT_32 blkMask
= (1 << blkSizeLog2
) - 1;
721 const UINT_32 blkOffset
= ComputeOffsetFromSwizzlePattern(pPattern
,
722 blkSizeLog2
+ 1, // +1 for nibble offset
727 const UINT_32 xb
= pIn
->x
/ output
.metaBlkWidth
;
728 const UINT_32 yb
= pIn
->y
/ output
.metaBlkHeight
;
729 const UINT_32 pb
= output
.pitch
/ output
.metaBlkWidth
;
730 const UINT_32 blkIndex
= (yb
* pb
) + xb
;
731 const UINT_32 pipeXor
= ((pIn
->pipeXor
& pipeMask
) << m_pipeInterleaveLog2
) & blkMask
;
733 pOut
->addr
= (static_cast<UINT_64
>(output
.dccRamSliceSize
) * pIn
->slice
) +
734 (blkIndex
* (1 << blkSizeLog2
)) +
735 ((blkOffset
>> 1) ^ pipeXor
);
743 ************************************************************************************************************************
744 * Gfx10Lib::HwlInitGlobalParams
747 * Initializes global parameters
750 * TRUE if all settings are valid
752 ************************************************************************************************************************
754 BOOL_32
Gfx10Lib::HwlInitGlobalParams(
755 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
757 BOOL_32 valid
= TRUE
;
758 GB_ADDR_CONFIG gbAddrConfig
;
760 gbAddrConfig
.u32All
= pCreateIn
->regValue
.gbAddrConfig
;
762 // These values are copied from CModel code
763 switch (gbAddrConfig
.bits
.NUM_PIPES
)
765 case ADDR_CONFIG_1_PIPE
:
769 case ADDR_CONFIG_2_PIPE
:
773 case ADDR_CONFIG_4_PIPE
:
777 case ADDR_CONFIG_8_PIPE
:
781 case ADDR_CONFIG_16_PIPE
:
785 case ADDR_CONFIG_32_PIPE
:
789 case ADDR_CONFIG_64_PIPE
:
794 ADDR_ASSERT_ALWAYS();
799 switch (gbAddrConfig
.bits
.PIPE_INTERLEAVE_SIZE
)
801 case ADDR_CONFIG_PIPE_INTERLEAVE_256B
:
802 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_256B
;
803 m_pipeInterleaveLog2
= 8;
805 case ADDR_CONFIG_PIPE_INTERLEAVE_512B
:
806 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_512B
;
807 m_pipeInterleaveLog2
= 9;
809 case ADDR_CONFIG_PIPE_INTERLEAVE_1KB
:
810 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_1KB
;
811 m_pipeInterleaveLog2
= 10;
813 case ADDR_CONFIG_PIPE_INTERLEAVE_2KB
:
814 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_2KB
;
815 m_pipeInterleaveLog2
= 11;
818 ADDR_ASSERT_ALWAYS();
823 // Addr::V2::Lib::ComputePipeBankXor()/ComputeSlicePipeBankXor() requires pipe interleave to be exactly 8 bits, and
824 // any larger value requires a post-process (left shift) on the output pipeBankXor bits.
825 ADDR_ASSERT(m_pipeInterleaveBytes
== ADDR_PIPEINTERLEAVE_256B
);
827 switch (gbAddrConfig
.bits
.MAX_COMPRESSED_FRAGS
)
829 case ADDR_CONFIG_1_MAX_COMPRESSED_FRAGMENTS
:
831 m_maxCompFragLog2
= 0;
833 case ADDR_CONFIG_2_MAX_COMPRESSED_FRAGMENTS
:
835 m_maxCompFragLog2
= 1;
837 case ADDR_CONFIG_4_MAX_COMPRESSED_FRAGMENTS
:
839 m_maxCompFragLog2
= 2;
841 case ADDR_CONFIG_8_MAX_COMPRESSED_FRAGMENTS
:
843 m_maxCompFragLog2
= 3;
846 ADDR_ASSERT_ALWAYS();
851 if (m_settings
.supportRbPlus
)
853 m_numPkrLog2
= gbAddrConfig
.bits
.NUM_PKRS
;
854 m_numSaLog2
= (m_numPkrLog2
> 0) ? (m_numPkrLog2
- 1) : 0;
856 ADDR_ASSERT((m_numPkrLog2
<= m_pipesLog2
) && ((m_pipesLog2
- m_numPkrLog2
) <= 2));
858 const UINT_32 maxPipeInterleaveType
= 3;
860 m_colorBaseIndex
= sizeof(SW_64K_R_X_1xaa_RBPLUS
) /
861 sizeof(SW_64K_R_X_1xaa_RBPLUS
[0]) /
862 maxPipeInterleaveType
*
863 (m_pipeInterleaveLog2
- 8);
864 m_htileBaseIndex
= sizeof(HTILE_64K_RBPLUS
) /
865 sizeof(HTILE_64K_RBPLUS
[0]) /
866 maxPipeInterleaveType
*
867 (m_pipeInterleaveLog2
- 8);
869 // Skip unaligned case
870 m_htileBaseIndex
+= MaxNumOfAA
;
872 if (m_numPkrLog2
< 2)
874 m_colorBaseIndex
+= m_pipesLog2
* MaxNumOfBpp
;
875 m_htileBaseIndex
+= m_pipesLog2
* MaxNumOfAA
;
879 m_colorBaseIndex
+= (2 * m_numPkrLog2
- 2 + m_pipesLog2
) * MaxNumOfBpp
;
881 const UINT_32 htilePipePerPkr
= 4;
883 m_htileBaseIndex
+= (m_numPkrLog2
- 1) * htilePipePerPkr
* MaxNumOfAA
+
884 (m_pipesLog2
+ 1 - m_numPkrLog2
) * MaxNumOfAA
;
889 const UINT_32 numPipeType
= static_cast<UINT_32
>(ADDR_CONFIG_64_PIPE
) -
890 static_cast<UINT_32
>(ADDR_CONFIG_1_PIPE
) +
893 m_colorBaseIndex
= (m_pipeInterleaveLog2
- 8) * (MaxNumOfBpp
* numPipeType
) +
894 (m_pipesLog2
* MaxNumOfBpp
);
896 m_htileBaseIndex
= (m_pipeInterleaveLog2
- 8) * (MaxNumOfAA
* (numPipeType
+ 1)) +
897 (m_pipesLog2
+ 1) * MaxNumOfAA
;
909 ************************************************************************************************************************
910 * Gfx10Lib::HwlConvertChipFamily
913 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
916 ************************************************************************************************************************
918 ChipFamily
Gfx10Lib::HwlConvertChipFamily(
919 UINT_32 chipFamily
, ///< [in] chip family defined in atiih.h
920 UINT_32 chipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
922 ChipFamily family
= ADDR_CHIP_FAMILY_NAVI
;
924 m_settings
.dccUnsup3DSwDis
= 1;
929 m_settings
.isDcn2
= 1;
932 ADDR_ASSERT(!"Unknown chip family");
936 m_settings
.dsMipmapHtileFix
= 1;
938 if (ASICREV_IS_NAVI10_P(chipRevision
))
940 m_settings
.dsMipmapHtileFix
= 0;
943 m_configFlags
.use32bppFor422Fmt
= TRUE
;
949 ************************************************************************************************************************
950 * Gfx10Lib::GetBlk256SizeLog2
957 ************************************************************************************************************************
959 void Gfx10Lib::GetBlk256SizeLog2(
960 AddrResourceType resourceType
, ///< [in] Resource type
961 AddrSwizzleMode swizzleMode
, ///< [in] Swizzle mode
962 UINT_32 elemLog2
, ///< [in] element size log2
963 UINT_32 numSamplesLog2
, ///< [in] number of samples
964 Dim3d
* pBlock
///< [out] block size
967 if (IsThin(resourceType
, swizzleMode
))
969 UINT_32 blockBits
= 8 - elemLog2
;
971 if (IsZOrderSwizzle(swizzleMode
))
973 blockBits
-= numSamplesLog2
;
976 pBlock
->w
= (blockBits
>> 1) + (blockBits
& 1);
977 pBlock
->h
= (blockBits
>> 1);
982 ADDR_ASSERT(IsThick(resourceType
, swizzleMode
));
984 UINT_32 blockBits
= 8 - elemLog2
;
986 pBlock
->d
= (blockBits
/ 3) + (((blockBits
% 3) > 0) ? 1 : 0);
987 pBlock
->w
= (blockBits
/ 3) + (((blockBits
% 3) > 1) ? 1 : 0);
988 pBlock
->h
= (blockBits
/ 3);
993 ************************************************************************************************************************
994 * Gfx10Lib::GetCompressedBlockSizeLog2
997 * Get compress block size
1001 ************************************************************************************************************************
1003 void Gfx10Lib::GetCompressedBlockSizeLog2(
1004 Gfx10DataType dataType
, ///< [in] Data type
1005 AddrResourceType resourceType
, ///< [in] Resource type
1006 AddrSwizzleMode swizzleMode
, ///< [in] Swizzle mode
1007 UINT_32 elemLog2
, ///< [in] element size log2
1008 UINT_32 numSamplesLog2
, ///< [in] number of samples
1009 Dim3d
* pBlock
///< [out] block size
1012 if (dataType
== Gfx10DataColor
)
1014 GetBlk256SizeLog2(resourceType
, swizzleMode
, elemLog2
, numSamplesLog2
, pBlock
);
1018 ADDR_ASSERT((dataType
== Gfx10DataDepthStencil
) || (dataType
== Gfx10DataFmask
));
1026 ************************************************************************************************************************
1027 * Gfx10Lib::GetMetaOverlapLog2
1030 * Get meta block overlap
1034 ************************************************************************************************************************
1036 INT_32
Gfx10Lib::GetMetaOverlapLog2(
1037 Gfx10DataType dataType
, ///< [in] Data type
1038 AddrResourceType resourceType
, ///< [in] Resource type
1039 AddrSwizzleMode swizzleMode
, ///< [in] Swizzle mode
1040 UINT_32 elemLog2
, ///< [in] element size log2
1041 UINT_32 numSamplesLog2
///< [in] number of samples
1047 GetCompressedBlockSizeLog2(dataType
, resourceType
, swizzleMode
, elemLog2
, numSamplesLog2
, &compBlock
);
1048 GetBlk256SizeLog2(resourceType
, swizzleMode
, elemLog2
, numSamplesLog2
, µBlock
);
1050 const INT_32 compSizeLog2
= compBlock
.w
+ compBlock
.h
+ compBlock
.d
;
1051 const INT_32 blk256SizeLog2
= microBlock
.w
+ microBlock
.h
+ microBlock
.d
;
1052 const INT_32 maxSizeLog2
= Max(compSizeLog2
, blk256SizeLog2
);
1053 const INT_32 numPipesLog2
= GetEffectiveNumPipes();
1054 INT_32 overlap
= numPipesLog2
- maxSizeLog2
;
1056 if ((numPipesLog2
> 1) && m_settings
.supportRbPlus
)
1061 // In 16Bpp 8xaa, we lose 1 overlap bit because the block size reduction eats into a pipe anchor bit (y4)
1062 if ((elemLog2
== 4) && (numSamplesLog2
== 3))
1066 overlap
= Max(overlap
, 0);
1071 ************************************************************************************************************************
1072 * Gfx10Lib::Get3DMetaOverlapLog2
1075 * Get 3d meta block overlap
1079 ************************************************************************************************************************
1081 INT_32
Gfx10Lib::Get3DMetaOverlapLog2(
1082 AddrResourceType resourceType
, ///< [in] Resource type
1083 AddrSwizzleMode swizzleMode
, ///< [in] Swizzle mode
1084 UINT_32 elemLog2
///< [in] element size log2
1088 GetBlk256SizeLog2(resourceType
, swizzleMode
, elemLog2
, 0, µBlock
);
1090 INT_32 overlap
= GetEffectiveNumPipes() - static_cast<INT_32
>(microBlock
.w
);
1092 if (m_settings
.supportRbPlus
)
1097 if ((overlap
< 0) || (IsStandardSwizzle(resourceType
, swizzleMode
) == TRUE
))
1105 ************************************************************************************************************************
1106 * Gfx10Lib::GetPipeRotateAmount
1109 * Get pipe rotate amount
1112 * Pipe rotate amount
1113 ************************************************************************************************************************
1116 INT_32
Gfx10Lib::GetPipeRotateAmount(
1117 AddrResourceType resourceType
, ///< [in] Resource type
1118 AddrSwizzleMode swizzleMode
///< [in] Swizzle mode
1123 if (m_settings
.supportRbPlus
&& (m_pipesLog2
>= (m_numSaLog2
+ 1)) && (m_pipesLog2
> 1))
1125 amount
= ((m_pipesLog2
== (m_numSaLog2
+ 1)) && IsRbAligned(resourceType
, swizzleMode
)) ?
1126 1 : m_pipesLog2
- (m_numSaLog2
+ 1);
1133 ************************************************************************************************************************
1134 * Gfx10Lib::GetMetaBlkSize
1137 * Get metadata block size
1141 ************************************************************************************************************************
1143 UINT_32
Gfx10Lib::GetMetaBlkSize(
1144 Gfx10DataType dataType
, ///< [in] Data type
1145 AddrResourceType resourceType
, ///< [in] Resource type
1146 AddrSwizzleMode swizzleMode
, ///< [in] Swizzle mode
1147 UINT_32 elemLog2
, ///< [in] element size log2
1148 UINT_32 numSamplesLog2
, ///< [in] number of samples
1149 BOOL_32 pipeAlign
, ///< [in] pipe align
1150 Dim3d
* pBlock
///< [out] block size
1153 INT_32 metablkSizeLog2
;
1154 const INT_32 metaElemSizeLog2
= GetMetaElementSizeLog2(dataType
);
1155 const INT_32 metaCacheSizeLog2
= GetMetaCacheSizeLog2(dataType
);
1156 const INT_32 compBlkSizeLog2
= (dataType
== Gfx10DataColor
) ? 8 : 6 + numSamplesLog2
+ elemLog2
;
1157 const INT_32 metaBlkSamplesLog2
= (dataType
== Gfx10DataDepthStencil
) ?
1158 numSamplesLog2
: Min(numSamplesLog2
, m_maxCompFragLog2
);
1159 const INT_32 dataBlkSizeLog2
= GetBlockSizeLog2(swizzleMode
);
1160 INT_32 numPipesLog2
= m_pipesLog2
;
1162 if (IsThin(resourceType
, swizzleMode
))
1164 if ((pipeAlign
== FALSE
) ||
1165 (IsStandardSwizzle(resourceType
, swizzleMode
) == TRUE
) ||
1166 (IsDisplaySwizzle(resourceType
, swizzleMode
) == TRUE
))
1170 metablkSizeLog2
= Max(static_cast<INT_32
>(m_pipeInterleaveLog2
) + numPipesLog2
, 12);
1171 metablkSizeLog2
= Min(metablkSizeLog2
, dataBlkSizeLog2
);
1175 metablkSizeLog2
= Min(dataBlkSizeLog2
, 12);
1180 if (m_settings
.supportRbPlus
&& (m_pipesLog2
== m_numSaLog2
+ 1) && (m_pipesLog2
> 1))
1185 INT_32 pipeRotateLog2
= GetPipeRotateAmount(resourceType
, swizzleMode
);
1187 if (numPipesLog2
>= 4)
1189 INT_32 overlapLog2
= GetMetaOverlapLog2(dataType
, resourceType
, swizzleMode
, elemLog2
, numSamplesLog2
);
1191 // In 16Bpe 8xaa, we have an extra overlap bit
1192 if ((pipeRotateLog2
> 0) &&
1194 (numSamplesLog2
== 3) &&
1195 (IsZOrderSwizzle(swizzleMode
) || (GetEffectiveNumPipes() > 3)))
1200 metablkSizeLog2
= metaCacheSizeLog2
+ overlapLog2
+ numPipesLog2
;
1201 metablkSizeLog2
= Max(metablkSizeLog2
, static_cast<INT_32
>(m_pipeInterleaveLog2
) + numPipesLog2
);
1203 if (m_settings
.supportRbPlus
&&
1204 IsRtOptSwizzle(swizzleMode
) &&
1205 (numPipesLog2
== 6) &&
1206 (numSamplesLog2
== 3) &&
1207 (m_maxCompFragLog2
== 3) &&
1208 (metablkSizeLog2
< 15))
1210 metablkSizeLog2
= 15;
1215 metablkSizeLog2
= Max(static_cast<INT_32
>(m_pipeInterleaveLog2
) + numPipesLog2
, 12);
1218 if (dataType
== Gfx10DataDepthStencil
)
1220 // For htile surfaces, pad meta block size to 2K * num_pipes
1221 metablkSizeLog2
= Max(metablkSizeLog2
, 11 + numPipesLog2
);
1224 const INT_32 compFragLog2
= Min(m_maxCompFragLog2
, numSamplesLog2
);
1226 if (IsRtOptSwizzle(swizzleMode
) && (compFragLog2
> 1) && (pipeRotateLog2
>= 1))
1228 const INT_32 tmp
= 8 + m_pipesLog2
+ Max(pipeRotateLog2
, compFragLog2
- 1);
1230 metablkSizeLog2
= Max(metablkSizeLog2
, tmp
);
1234 const INT_32 metablkBitsLog2
=
1235 metablkSizeLog2
+ compBlkSizeLog2
- elemLog2
- metaBlkSamplesLog2
- metaElemSizeLog2
;
1236 pBlock
->w
= 1 << ((metablkBitsLog2
>> 1) + (metablkBitsLog2
& 1));
1237 pBlock
->h
= 1 << (metablkBitsLog2
>> 1);
1242 ADDR_ASSERT(IsThick(resourceType
, swizzleMode
));
1246 if (m_settings
.supportRbPlus
&&
1247 (m_pipesLog2
== m_numSaLog2
+ 1) &&
1248 (m_pipesLog2
> 1) &&
1249 IsRbAligned(resourceType
, swizzleMode
))
1254 const INT_32 overlapLog2
= Get3DMetaOverlapLog2(resourceType
, swizzleMode
, elemLog2
);
1256 metablkSizeLog2
= metaCacheSizeLog2
+ overlapLog2
+ numPipesLog2
;
1257 metablkSizeLog2
= Max(metablkSizeLog2
, static_cast<INT_32
>(m_pipeInterleaveLog2
) + numPipesLog2
);
1258 metablkSizeLog2
= Max(metablkSizeLog2
, 12);
1262 metablkSizeLog2
= 12;
1265 const INT_32 metablkBitsLog2
=
1266 metablkSizeLog2
+ compBlkSizeLog2
- elemLog2
- metaBlkSamplesLog2
- metaElemSizeLog2
;
1267 pBlock
->w
= 1 << ((metablkBitsLog2
/ 3) + (((metablkBitsLog2
% 3) > 0) ? 1 : 0));
1268 pBlock
->h
= 1 << ((metablkBitsLog2
/ 3) + (((metablkBitsLog2
% 3) > 1) ? 1 : 0));
1269 pBlock
->d
= 1 << (metablkBitsLog2
/ 3);
1272 return (1 << static_cast<UINT_32
>(metablkSizeLog2
));
1276 ************************************************************************************************************************
1277 * Gfx10Lib::ConvertSwizzlePatternToEquation
1280 * Convert swizzle pattern to equation.
1284 ************************************************************************************************************************
1286 VOID
Gfx10Lib::ConvertSwizzlePatternToEquation(
1287 UINT_32 elemLog2
, ///< [in] element bytes log2
1288 AddrResourceType rsrcType
, ///< [in] resource type
1289 AddrSwizzleMode swMode
, ///< [in] swizzle mode
1290 const UINT_64
* pPattern
, ///< [in] swizzle pattern
1291 ADDR_EQUATION
* pEquation
) ///< [out] equation converted from swizzle pattern
1294 const ADDR_BIT_SETTING
* pSwizzle
= reinterpret_cast<const ADDR_BIT_SETTING
*>(pPattern
);
1295 const UINT_32 blockSizeLog2
= GetBlockSizeLog2(swMode
);
1297 pEquation
->numBits
= blockSizeLog2
;
1298 pEquation
->stackedDepthSlices
= FALSE
;
1300 for (UINT_32 i
= 0; i
< elemLog2
; i
++)
1302 pEquation
->addr
[i
].channel
= 0;
1303 pEquation
->addr
[i
].valid
= 1;
1304 pEquation
->addr
[i
].index
= i
;
1307 if (IsXor(swMode
) == FALSE
)
1309 for (UINT_32 i
= elemLog2
; i
< blockSizeLog2
; i
++)
1311 ADDR_ASSERT(IsPow2(pSwizzle
[i
].value
));
1313 if (pSwizzle
[i
].x
!= 0)
1315 ADDR_ASSERT(IsPow2(static_cast<UINT_32
>(pSwizzle
[i
].x
)));
1317 pEquation
->addr
[i
].channel
= 0;
1318 pEquation
->addr
[i
].valid
= 1;
1319 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].x
) + elemLog2
;
1321 else if (pSwizzle
[i
].y
!= 0)
1323 ADDR_ASSERT(IsPow2(static_cast<UINT_32
>(pSwizzle
[i
].y
)));
1325 pEquation
->addr
[i
].channel
= 1;
1326 pEquation
->addr
[i
].valid
= 1;
1327 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].y
);
1331 ADDR_ASSERT(pSwizzle
[i
].z
!= 0);
1332 ADDR_ASSERT(IsPow2(static_cast<UINT_32
>(pSwizzle
[i
].z
)));
1334 pEquation
->addr
[i
].channel
= 2;
1335 pEquation
->addr
[i
].valid
= 1;
1336 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].z
);
1339 pEquation
->xor1
[i
].value
= 0;
1340 pEquation
->xor2
[i
].value
= 0;
1343 else if (IsThin(rsrcType
, swMode
))
1345 const UINT_32 blkXLog2
= (blockSizeLog2
== 12) ? Block4K_Log2_2d
[elemLog2
].w
: Block64K_Log2_2d
[elemLog2
].w
;
1346 const UINT_32 blkYLog2
= (blockSizeLog2
== 12) ? Block4K_Log2_2d
[elemLog2
].h
: Block64K_Log2_2d
[elemLog2
].h
;
1347 const UINT_32 blkXMask
= (1 << blkXLog2
) - 1;
1348 const UINT_32 blkYMask
= (1 << blkYLog2
) - 1;
1350 ADDR_BIT_SETTING swizzle
[ADDR_MAX_EQUATION_BIT
];
1353 UINT_32 bMask
= (1 << elemLog2
) - 1;
1355 for (UINT_32 i
= elemLog2
; i
< blockSizeLog2
; i
++)
1357 if (IsPow2(pSwizzle
[i
].value
))
1359 if (pSwizzle
[i
].x
!= 0)
1361 ADDR_ASSERT((xMask
& pSwizzle
[i
].x
) == 0);
1362 xMask
|= pSwizzle
[i
].x
;
1364 const UINT_32 xLog2
= Log2(pSwizzle
[i
].x
);
1366 ADDR_ASSERT(xLog2
< blkXLog2
);
1368 pEquation
->addr
[i
].channel
= 0;
1369 pEquation
->addr
[i
].valid
= 1;
1370 pEquation
->addr
[i
].index
= xLog2
+ elemLog2
;
1374 ADDR_ASSERT(pSwizzle
[i
].y
!= 0);
1375 ADDR_ASSERT((yMask
& pSwizzle
[i
].y
) == 0);
1376 yMask
|= pSwizzle
[i
].y
;
1378 pEquation
->addr
[i
].channel
= 1;
1379 pEquation
->addr
[i
].valid
= 1;
1380 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].y
);
1382 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkYLog2
);
1385 swizzle
[i
].value
= 0;
1390 if (pSwizzle
[i
].z
!= 0)
1392 ADDR_ASSERT(IsPow2(static_cast<UINT_32
>(pSwizzle
[i
].z
)));
1394 pEquation
->xor2
[i
].channel
= 2;
1395 pEquation
->xor2
[i
].valid
= 1;
1396 pEquation
->xor2
[i
].index
= Log2(pSwizzle
[i
].z
);
1399 swizzle
[i
].x
= pSwizzle
[i
].x
;
1400 swizzle
[i
].y
= pSwizzle
[i
].y
;
1401 swizzle
[i
].z
= swizzle
[i
].s
= 0;
1403 ADDR_ASSERT(IsPow2(swizzle
[i
].value
) == FALSE
);
1405 const UINT_32 xHi
= swizzle
[i
].x
& (~blkXMask
);
1409 ADDR_ASSERT(IsPow2(xHi
));
1410 ADDR_ASSERT(pEquation
->xor1
[i
].value
== 0);
1412 pEquation
->xor1
[i
].channel
= 0;
1413 pEquation
->xor1
[i
].valid
= 1;
1414 pEquation
->xor1
[i
].index
= Log2(xHi
) + elemLog2
;
1416 swizzle
[i
].x
&= blkXMask
;
1419 const UINT_32 yHi
= swizzle
[i
].y
& (~blkYMask
);
1423 ADDR_ASSERT(IsPow2(yHi
));
1427 ADDR_ASSERT(pEquation
->xor1
[i
].value
== 0);
1428 pEquation
->xor1
[i
].channel
= 1;
1429 pEquation
->xor1
[i
].valid
= 1;
1430 pEquation
->xor1
[i
].index
= Log2(yHi
);
1434 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1435 pEquation
->xor2
[i
].channel
= 1;
1436 pEquation
->xor2
[i
].valid
= 1;
1437 pEquation
->xor2
[i
].index
= Log2(yHi
);
1440 swizzle
[i
].y
&= blkYMask
;
1443 if (swizzle
[i
].value
== 0)
1450 const UINT_32 pipeIntMask
= (1 << m_pipeInterleaveLog2
) - 1;
1451 const UINT_32 blockMask
= (1 << blockSizeLog2
) - 1;
1453 ADDR_ASSERT((bMask
& pipeIntMask
) == pipeIntMask
);
1455 while (bMask
!= blockMask
)
1457 for (UINT_32 i
= m_pipeInterleaveLog2
; i
< blockSizeLog2
; i
++)
1459 if ((bMask
& (1 << i
)) == 0)
1461 if (IsPow2(swizzle
[i
].value
))
1463 if (swizzle
[i
].x
!= 0)
1465 ADDR_ASSERT((xMask
& swizzle
[i
].x
) == 0);
1466 xMask
|= swizzle
[i
].x
;
1468 const UINT_32 xLog2
= Log2(swizzle
[i
].x
);
1470 ADDR_ASSERT(xLog2
< blkXLog2
);
1472 pEquation
->addr
[i
].channel
= 0;
1473 pEquation
->addr
[i
].valid
= 1;
1474 pEquation
->addr
[i
].index
= xLog2
+ elemLog2
;
1478 ADDR_ASSERT(swizzle
[i
].y
!= 0);
1479 ADDR_ASSERT((yMask
& swizzle
[i
].y
) == 0);
1480 yMask
|= swizzle
[i
].y
;
1482 pEquation
->addr
[i
].channel
= 1;
1483 pEquation
->addr
[i
].valid
= 1;
1484 pEquation
->addr
[i
].index
= Log2(swizzle
[i
].y
);
1486 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkYLog2
);
1489 swizzle
[i
].value
= 0;
1494 const UINT_32 x
= swizzle
[i
].x
& xMask
;
1495 const UINT_32 y
= swizzle
[i
].y
& yMask
;
1499 ADDR_ASSERT(IsPow2(x
));
1501 if (pEquation
->xor1
[i
].value
== 0)
1503 pEquation
->xor1
[i
].channel
= 0;
1504 pEquation
->xor1
[i
].valid
= 1;
1505 pEquation
->xor1
[i
].index
= Log2(x
) + elemLog2
;
1509 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1510 pEquation
->xor2
[i
].channel
= 0;
1511 pEquation
->xor2
[i
].valid
= 1;
1512 pEquation
->xor2
[i
].index
= Log2(x
) + elemLog2
;
1518 ADDR_ASSERT(IsPow2(y
));
1520 if (pEquation
->xor1
[i
].value
== 0)
1522 pEquation
->xor1
[i
].channel
= 1;
1523 pEquation
->xor1
[i
].valid
= 1;
1524 pEquation
->xor1
[i
].index
= Log2(y
);
1528 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1529 pEquation
->xor2
[i
].channel
= 1;
1530 pEquation
->xor2
[i
].valid
= 1;
1531 pEquation
->xor2
[i
].index
= Log2(y
);
1542 ADDR_ASSERT((xMask
== blkXMask
) && (yMask
== blkYMask
));
1544 else if (IsEquationCompatibleThick(rsrcType
, swMode
))
1546 const UINT_32 blkXLog2
= (blockSizeLog2
== 12) ? Block4K_Log2_3d
[elemLog2
].w
: Block64K_Log2_3d
[elemLog2
].w
;
1547 const UINT_32 blkYLog2
= (blockSizeLog2
== 12) ? Block4K_Log2_3d
[elemLog2
].h
: Block64K_Log2_3d
[elemLog2
].h
;
1548 const UINT_32 blkZLog2
= (blockSizeLog2
== 12) ? Block4K_Log2_3d
[elemLog2
].d
: Block64K_Log2_3d
[elemLog2
].d
;
1549 const UINT_32 blkXMask
= (1 << blkXLog2
) - 1;
1550 const UINT_32 blkYMask
= (1 << blkYLog2
) - 1;
1551 const UINT_32 blkZMask
= (1 << blkZLog2
) - 1;
1553 ADDR_BIT_SETTING swizzle
[ADDR_MAX_EQUATION_BIT
];
1557 UINT_32 bMask
= (1 << elemLog2
) - 1;
1559 for (UINT_32 i
= elemLog2
; i
< blockSizeLog2
; i
++)
1561 if (IsPow2(pSwizzle
[i
].value
))
1563 if (pSwizzle
[i
].x
!= 0)
1565 ADDR_ASSERT((xMask
& pSwizzle
[i
].x
) == 0);
1566 xMask
|= pSwizzle
[i
].x
;
1568 const UINT_32 xLog2
= Log2(pSwizzle
[i
].x
);
1570 ADDR_ASSERT(xLog2
< blkXLog2
);
1572 pEquation
->addr
[i
].channel
= 0;
1573 pEquation
->addr
[i
].valid
= 1;
1574 pEquation
->addr
[i
].index
= xLog2
+ elemLog2
;
1576 else if (pSwizzle
[i
].y
!= 0)
1578 ADDR_ASSERT((yMask
& pSwizzle
[i
].y
) == 0);
1579 yMask
|= pSwizzle
[i
].y
;
1581 pEquation
->addr
[i
].channel
= 1;
1582 pEquation
->addr
[i
].valid
= 1;
1583 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].y
);
1585 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkYLog2
);
1589 ADDR_ASSERT(pSwizzle
[i
].z
!= 0);
1590 ADDR_ASSERT((zMask
& pSwizzle
[i
].z
) == 0);
1591 zMask
|= pSwizzle
[i
].z
;
1593 pEquation
->addr
[i
].channel
= 2;
1594 pEquation
->addr
[i
].valid
= 1;
1595 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].z
);
1597 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkZLog2
);
1600 swizzle
[i
].value
= 0;
1605 swizzle
[i
].x
= pSwizzle
[i
].x
;
1606 swizzle
[i
].y
= pSwizzle
[i
].y
;
1607 swizzle
[i
].z
= pSwizzle
[i
].z
;
1610 ADDR_ASSERT(IsPow2(swizzle
[i
].value
) == FALSE
);
1612 const UINT_32 xHi
= swizzle
[i
].x
& (~blkXMask
);
1613 const UINT_32 yHi
= swizzle
[i
].y
& (~blkYMask
);
1614 const UINT_32 zHi
= swizzle
[i
].z
& (~blkZMask
);
1616 ADDR_ASSERT((xHi
== 0) || (yHi
== 0) || (zHi
== 0));
1620 ADDR_ASSERT(IsPow2(xHi
));
1621 ADDR_ASSERT(pEquation
->xor1
[i
].value
== 0);
1623 pEquation
->xor1
[i
].channel
= 0;
1624 pEquation
->xor1
[i
].valid
= 1;
1625 pEquation
->xor1
[i
].index
= Log2(xHi
) + elemLog2
;
1627 swizzle
[i
].x
&= blkXMask
;
1632 ADDR_ASSERT(IsPow2(yHi
));
1634 if (pEquation
->xor1
[i
].value
== 0)
1636 pEquation
->xor1
[i
].channel
= 1;
1637 pEquation
->xor1
[i
].valid
= 1;
1638 pEquation
->xor1
[i
].index
= Log2(yHi
);
1642 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1643 pEquation
->xor2
[i
].channel
= 1;
1644 pEquation
->xor2
[i
].valid
= 1;
1645 pEquation
->xor2
[i
].index
= Log2(yHi
);
1648 swizzle
[i
].y
&= blkYMask
;
1653 ADDR_ASSERT(IsPow2(zHi
));
1655 if (pEquation
->xor1
[i
].value
== 0)
1657 pEquation
->xor1
[i
].channel
= 2;
1658 pEquation
->xor1
[i
].valid
= 1;
1659 pEquation
->xor1
[i
].index
= Log2(zHi
);
1663 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1664 pEquation
->xor2
[i
].channel
= 2;
1665 pEquation
->xor2
[i
].valid
= 1;
1666 pEquation
->xor2
[i
].index
= Log2(zHi
);
1669 swizzle
[i
].z
&= blkZMask
;
1672 if (swizzle
[i
].value
== 0)
1679 const UINT_32 pipeIntMask
= (1 << m_pipeInterleaveLog2
) - 1;
1680 const UINT_32 blockMask
= (1 << blockSizeLog2
) - 1;
1682 ADDR_ASSERT((bMask
& pipeIntMask
) == pipeIntMask
);
1684 while (bMask
!= blockMask
)
1686 for (UINT_32 i
= m_pipeInterleaveLog2
; i
< blockSizeLog2
; i
++)
1688 if ((bMask
& (1 << i
)) == 0)
1690 if (IsPow2(swizzle
[i
].value
))
1692 if (swizzle
[i
].x
!= 0)
1694 ADDR_ASSERT((xMask
& swizzle
[i
].x
) == 0);
1695 xMask
|= swizzle
[i
].x
;
1697 const UINT_32 xLog2
= Log2(swizzle
[i
].x
);
1699 ADDR_ASSERT(xLog2
< blkXLog2
);
1701 pEquation
->addr
[i
].channel
= 0;
1702 pEquation
->addr
[i
].valid
= 1;
1703 pEquation
->addr
[i
].index
= xLog2
+ elemLog2
;
1705 else if (swizzle
[i
].y
!= 0)
1707 ADDR_ASSERT((yMask
& swizzle
[i
].y
) == 0);
1708 yMask
|= swizzle
[i
].y
;
1710 pEquation
->addr
[i
].channel
= 1;
1711 pEquation
->addr
[i
].valid
= 1;
1712 pEquation
->addr
[i
].index
= Log2(swizzle
[i
].y
);
1714 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkYLog2
);
1718 ADDR_ASSERT(swizzle
[i
].z
!= 0);
1719 ADDR_ASSERT((zMask
& swizzle
[i
].z
) == 0);
1720 zMask
|= swizzle
[i
].z
;
1722 pEquation
->addr
[i
].channel
= 2;
1723 pEquation
->addr
[i
].valid
= 1;
1724 pEquation
->addr
[i
].index
= Log2(swizzle
[i
].z
);
1726 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkZLog2
);
1729 swizzle
[i
].value
= 0;
1734 const UINT_32 x
= swizzle
[i
].x
& xMask
;
1735 const UINT_32 y
= swizzle
[i
].y
& yMask
;
1736 const UINT_32 z
= swizzle
[i
].z
& zMask
;
1740 ADDR_ASSERT(IsPow2(x
));
1742 if (pEquation
->xor1
[i
].value
== 0)
1744 pEquation
->xor1
[i
].channel
= 0;
1745 pEquation
->xor1
[i
].valid
= 1;
1746 pEquation
->xor1
[i
].index
= Log2(x
) + elemLog2
;
1750 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1751 pEquation
->xor2
[i
].channel
= 0;
1752 pEquation
->xor2
[i
].valid
= 1;
1753 pEquation
->xor2
[i
].index
= Log2(x
) + elemLog2
;
1759 ADDR_ASSERT(IsPow2(y
));
1761 if (pEquation
->xor1
[i
].value
== 0)
1763 pEquation
->xor1
[i
].channel
= 1;
1764 pEquation
->xor1
[i
].valid
= 1;
1765 pEquation
->xor1
[i
].index
= Log2(y
);
1769 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1770 pEquation
->xor2
[i
].channel
= 1;
1771 pEquation
->xor2
[i
].valid
= 1;
1772 pEquation
->xor2
[i
].index
= Log2(y
);
1778 ADDR_ASSERT(IsPow2(z
));
1780 if (pEquation
->xor1
[i
].value
== 0)
1782 pEquation
->xor1
[i
].channel
= 2;
1783 pEquation
->xor1
[i
].valid
= 1;
1784 pEquation
->xor1
[i
].index
= Log2(z
);
1788 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1789 pEquation
->xor2
[i
].channel
= 2;
1790 pEquation
->xor2
[i
].valid
= 1;
1791 pEquation
->xor2
[i
].index
= Log2(z
);
1803 ADDR_ASSERT((xMask
== blkXMask
) && (yMask
== blkYMask
) && (zMask
== blkZMask
));
1808 ************************************************************************************************************************
1809 * Gfx10Lib::InitEquationTable
1812 * Initialize Equation table.
1816 ************************************************************************************************************************
1818 VOID
Gfx10Lib::InitEquationTable()
1820 memset(m_equationTable
, 0, sizeof(m_equationTable
));
1822 for (UINT_32 rsrcTypeIdx
= 0; rsrcTypeIdx
< MaxRsrcType
; rsrcTypeIdx
++)
1824 const AddrResourceType rsrcType
= static_cast<AddrResourceType
>(rsrcTypeIdx
+ ADDR_RSRC_TEX_2D
);
1826 for (UINT_32 swModeIdx
= 0; swModeIdx
< MaxSwMode
; swModeIdx
++)
1828 const AddrSwizzleMode swMode
= static_cast<AddrSwizzleMode
>(swModeIdx
);
1830 for (UINT_32 elemLog2
= 0; elemLog2
< MaxElementBytesLog2
; elemLog2
++)
1832 UINT_32 equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
1833 const UINT_64
* pPattern
= GetSwizzlePattern(swMode
, rsrcType
, elemLog2
, 1);
1835 if (pPattern
!= NULL
)
1837 ADDR_EQUATION equation
= {};
1839 ConvertSwizzlePatternToEquation(elemLog2
, rsrcType
, swMode
, pPattern
, &equation
);
1841 equationIndex
= m_numEquations
;
1842 ADDR_ASSERT(equationIndex
< EquationTableSize
);
1844 m_equationTable
[equationIndex
] = equation
;
1849 m_equationLookupTable
[rsrcTypeIdx
][swModeIdx
][elemLog2
] = equationIndex
;
1856 ************************************************************************************************************************
1857 * Gfx10Lib::HwlGetEquationIndex
1860 * Interface function stub of GetEquationIndex
1864 ************************************************************************************************************************
1866 UINT_32
Gfx10Lib::HwlGetEquationIndex(
1867 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
1868 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
1871 UINT_32 equationIdx
= ADDR_INVALID_EQUATION_INDEX
;
1873 if ((pIn
->resourceType
== ADDR_RSRC_TEX_2D
) ||
1874 (pIn
->resourceType
== ADDR_RSRC_TEX_3D
))
1876 const UINT_32 rsrcTypeIdx
= static_cast<UINT_32
>(pIn
->resourceType
) - 1;
1877 const UINT_32 swModeIdx
= static_cast<UINT_32
>(pIn
->swizzleMode
);
1878 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
1880 equationIdx
= m_equationLookupTable
[rsrcTypeIdx
][swModeIdx
][elemLog2
];
1883 if (pOut
->pMipInfo
!= NULL
)
1885 for (UINT_32 i
= 0; i
< pIn
->numMipLevels
; i
++)
1887 pOut
->pMipInfo
[i
].equationIndex
= equationIdx
;
1895 ************************************************************************************************************************
1896 * Gfx10Lib::IsValidDisplaySwizzleMode
1899 * Check if a swizzle mode is supported by display engine
1902 * TRUE is swizzle mode is supported by display engine
1903 ************************************************************************************************************************
1905 BOOL_32
Gfx10Lib::IsValidDisplaySwizzleMode(
1906 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in] input structure
1909 ADDR_ASSERT(pIn
->resourceType
== ADDR_RSRC_TEX_2D
);
1911 BOOL_32 support
= FALSE
;
1913 if (m_settings
.isDcn2
)
1915 switch (pIn
->swizzleMode
)
1918 case ADDR_SW_4KB_D_X
:
1919 case ADDR_SW_64KB_D
:
1920 case ADDR_SW_64KB_D_T
:
1921 case ADDR_SW_64KB_D_X
:
1922 support
= (pIn
->bpp
== 64);
1925 case ADDR_SW_LINEAR
:
1927 case ADDR_SW_4KB_S_X
:
1928 case ADDR_SW_64KB_S
:
1929 case ADDR_SW_64KB_S_T
:
1930 case ADDR_SW_64KB_S_X
:
1931 case ADDR_SW_64KB_R_X
:
1932 support
= (pIn
->bpp
<= 64);
1941 ADDR_NOT_IMPLEMENTED();
1948 ************************************************************************************************************************
1949 * Gfx10Lib::GetMaxNumMipsInTail
1952 * Return max number of mips in tails
1955 * Max number of mips in tails
1956 ************************************************************************************************************************
1958 UINT_32
Gfx10Lib::GetMaxNumMipsInTail(
1959 UINT_32 blockSizeLog2
, ///< block size log2
1960 BOOL_32 isThin
///< is thin or thick
1963 UINT_32 effectiveLog2
= blockSizeLog2
;
1965 if (isThin
== FALSE
)
1967 effectiveLog2
-= (blockSizeLog2
- 8) / 3;
1970 return (effectiveLog2
<= 11) ? (1 + (1 << (effectiveLog2
- 9))) : (effectiveLog2
- 4);
1974 ************************************************************************************************************************
1975 * Gfx10Lib::HwlComputePipeBankXor
1978 * Generate a PipeBankXor value to be ORed into bits above pipeInterleaveBits of address
1982 ************************************************************************************************************************
1984 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputePipeBankXor(
1985 const ADDR2_COMPUTE_PIPEBANKXOR_INPUT
* pIn
, ///< [in] input structure
1986 ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT
* pOut
///< [out] output structure
1989 if (IsNonPrtXor(pIn
->swizzleMode
))
1991 const UINT_32 blockBits
= GetBlockSizeLog2(pIn
->swizzleMode
);
1992 const UINT_32 pipeBits
= GetPipeXorBits(blockBits
);
1993 const UINT_32 bankBits
= GetBankXorBits(blockBits
);
1995 UINT_32 pipeXor
= 0;
1996 UINT_32 bankXor
= 0;
2000 if (blockBits
== 16)
2002 const UINT_32 XorPatternLen
= 8;
2003 static const UINT_32 XorBank1b
[XorPatternLen
] = {0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80};
2004 static const UINT_32 XorBank2b
[XorPatternLen
] = {0x00, 0x80, 0x40, 0xC0, 0x80, 0x00, 0xC0, 0x40};
2005 static const UINT_32 XorBank3b
[XorPatternLen
] = {0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0};
2007 const UINT_32 index
= pIn
->surfIndex
% XorPatternLen
;
2011 bankXor
= XorBank1b
[index
];
2013 else if (bankBits
== 2)
2015 bankXor
= XorBank2b
[index
];
2019 bankXor
= XorBank3b
[index
];
2023 bankXor
>>= (2 - pipeBits
);
2029 pOut
->pipeBankXor
= bankXor
| pipeXor
;
2033 pOut
->pipeBankXor
= 0;
2040 ************************************************************************************************************************
2041 * Gfx10Lib::HwlComputeSlicePipeBankXor
2044 * Generate slice PipeBankXor value based on base PipeBankXor value and slice id
2048 ************************************************************************************************************************
2050 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSlicePipeBankXor(
2051 const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT
* pIn
, ///< [in] input structure
2052 ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT
* pOut
///< [out] output structure
2055 if (IsNonPrtXor(pIn
->swizzleMode
))
2057 const UINT_32 blockBits
= GetBlockSizeLog2(pIn
->swizzleMode
);
2058 const UINT_32 pipeBits
= GetPipeXorBits(blockBits
);
2059 const UINT_32 pipeXor
= ReverseBitVector(pIn
->slice
, pipeBits
);
2061 pOut
->pipeBankXor
= pIn
->basePipeBankXor
^ pipeXor
;
2065 pOut
->pipeBankXor
= 0;
2072 ************************************************************************************************************************
2073 * Gfx10Lib::HwlComputeSubResourceOffsetForSwizzlePattern
2076 * Compute sub resource offset to support swizzle pattern
2080 ************************************************************************************************************************
2082 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSubResourceOffsetForSwizzlePattern(
2083 const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT
* pIn
, ///< [in] input structure
2084 ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT
* pOut
///< [out] output structure
2087 ADDR_ASSERT(IsThin(pIn
->resourceType
, pIn
->swizzleMode
));
2089 pOut
->offset
= pIn
->slice
* pIn
->sliceSize
+ pIn
->macroBlockOffset
;
2095 ************************************************************************************************************************
2096 * Gfx10Lib::ValidateNonSwModeParams
2099 * Validate compute surface info params except swizzle mode
2102 * TRUE if parameters are valid, FALSE otherwise
2103 ************************************************************************************************************************
2105 BOOL_32
Gfx10Lib::ValidateNonSwModeParams(
2106 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
) const
2108 BOOL_32 valid
= TRUE
;
2110 if ((pIn
->bpp
== 0) || (pIn
->bpp
> 128) || (pIn
->width
== 0) || (pIn
->numFrags
> 8) || (pIn
->numSamples
> 16))
2112 ADDR_ASSERT_ALWAYS();
2116 if (pIn
->resourceType
>= ADDR_RSRC_MAX_TYPE
)
2118 ADDR_ASSERT_ALWAYS();
2122 const ADDR2_SURFACE_FLAGS flags
= pIn
->flags
;
2123 const AddrResourceType rsrcType
= pIn
->resourceType
;
2124 const BOOL_32 mipmap
= (pIn
->numMipLevels
> 1);
2125 const BOOL_32 msaa
= (pIn
->numFrags
> 1);
2126 const BOOL_32 display
= flags
.display
;
2127 const BOOL_32 tex3d
= IsTex3d(rsrcType
);
2128 const BOOL_32 tex2d
= IsTex2d(rsrcType
);
2129 const BOOL_32 tex1d
= IsTex1d(rsrcType
);
2130 const BOOL_32 stereo
= flags
.qbStereo
;
2132 // Resource type check
2135 if (msaa
|| display
|| stereo
)
2137 ADDR_ASSERT_ALWAYS();
2143 if ((msaa
&& mipmap
) || (stereo
&& msaa
) || (stereo
&& mipmap
))
2145 ADDR_ASSERT_ALWAYS();
2151 if (msaa
|| display
|| stereo
)
2153 ADDR_ASSERT_ALWAYS();
2159 ADDR_ASSERT_ALWAYS();
2167 ************************************************************************************************************************
2168 * Gfx10Lib::ValidateSwModeParams
2171 * Validate compute surface info related to swizzle mode
2174 * TRUE if parameters are valid, FALSE otherwise
2175 ************************************************************************************************************************
2177 BOOL_32
Gfx10Lib::ValidateSwModeParams(
2178 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
) const
2180 BOOL_32 valid
= TRUE
;
2182 if (pIn
->swizzleMode
>= ADDR_SW_MAX_TYPE
)
2184 ADDR_ASSERT_ALWAYS();
2188 const ADDR2_SURFACE_FLAGS flags
= pIn
->flags
;
2189 const AddrResourceType rsrcType
= pIn
->resourceType
;
2190 const AddrSwizzleMode swizzle
= pIn
->swizzleMode
;
2191 const BOOL_32 msaa
= (pIn
->numFrags
> 1);
2192 const BOOL_32 zbuffer
= flags
.depth
|| flags
.stencil
;
2193 const BOOL_32 color
= flags
.color
;
2194 const BOOL_32 display
= flags
.display
;
2195 const BOOL_32 tex3d
= IsTex3d(rsrcType
);
2196 const BOOL_32 tex2d
= IsTex2d(rsrcType
);
2197 const BOOL_32 tex1d
= IsTex1d(rsrcType
);
2198 const BOOL_32 thin3d
= flags
.view3dAs2dArray
;
2199 const BOOL_32 linear
= IsLinear(swizzle
);
2200 const BOOL_32 blk256B
= IsBlock256b(swizzle
);
2201 const BOOL_32 isNonPrtXor
= IsNonPrtXor(swizzle
);
2202 const BOOL_32 prt
= flags
.prt
;
2205 if ((pIn
->numFrags
> 1) &&
2206 (GetBlockSize(swizzle
) < (m_pipeInterleaveBytes
* pIn
->numFrags
)))
2208 // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
2209 ADDR_ASSERT_ALWAYS();
2213 if (display
&& (IsValidDisplaySwizzleMode(pIn
) == FALSE
))
2215 ADDR_ASSERT_ALWAYS();
2219 if ((pIn
->bpp
== 96) && (linear
== FALSE
))
2221 ADDR_ASSERT_ALWAYS();
2225 const UINT_32 swizzleMask
= 1 << swizzle
;
2227 // Resource type check
2230 if ((swizzleMask
& Gfx10Rsrc1dSwModeMask
) == 0)
2232 ADDR_ASSERT_ALWAYS();
2238 if (((swizzleMask
& Gfx10Rsrc2dSwModeMask
) == 0) ||
2239 (prt
&& ((swizzleMask
& Gfx10Rsrc2dPrtSwModeMask
) == 0)))
2241 ADDR_ASSERT_ALWAYS();
2247 if (((swizzleMask
& Gfx10Rsrc3dSwModeMask
) == 0) ||
2248 (prt
&& ((swizzleMask
& Gfx10Rsrc3dPrtSwModeMask
) == 0)) ||
2249 (thin3d
&& ((swizzleMask
& Gfx10Rsrc3dThinSwModeMask
) == 0)))
2251 ADDR_ASSERT_ALWAYS();
2256 // Swizzle type check
2259 if (zbuffer
|| msaa
|| (pIn
->bpp
== 0) || ((pIn
->bpp
% 8) != 0))
2261 ADDR_ASSERT_ALWAYS();
2265 else if (IsZOrderSwizzle(swizzle
))
2267 if ((pIn
->bpp
> 64) ||
2268 (msaa
&& (color
|| (pIn
->bpp
> 32))) ||
2269 ElemLib::IsBlockCompressed(pIn
->format
) ||
2270 ElemLib::IsMacroPixelPacked(pIn
->format
))
2272 ADDR_ASSERT_ALWAYS();
2276 else if (IsStandardSwizzle(rsrcType
, swizzle
))
2278 if (zbuffer
|| msaa
)
2280 ADDR_ASSERT_ALWAYS();
2284 else if (IsDisplaySwizzle(rsrcType
, swizzle
))
2286 if (zbuffer
|| msaa
)
2288 ADDR_ASSERT_ALWAYS();
2292 else if (IsRtOptSwizzle(swizzle
))
2296 ADDR_ASSERT_ALWAYS();
2302 ADDR_ASSERT_ALWAYS();
2309 if (zbuffer
|| tex3d
|| msaa
)
2311 ADDR_ASSERT_ALWAYS();
2320 ************************************************************************************************************************
2321 * Gfx10Lib::HwlComputeSurfaceInfoSanityCheck
2324 * Compute surface info sanity check
2328 ************************************************************************************************************************
2330 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSurfaceInfoSanityCheck(
2331 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in] input structure
2334 return ValidateNonSwModeParams(pIn
) && ValidateSwModeParams(pIn
) ? ADDR_OK
: ADDR_INVALIDPARAMS
;
2338 ************************************************************************************************************************
2339 * Gfx10Lib::HwlGetPreferredSurfaceSetting
2342 * Internal function to get suggested surface information for cliet to use
2346 ************************************************************************************************************************
2348 ADDR_E_RETURNCODE
Gfx10Lib::HwlGetPreferredSurfaceSetting(
2349 const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT
* pIn
, ///< [in] input structure
2350 ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT
* pOut
///< [out] output structure
2353 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2355 if (pIn
->flags
.fmask
)
2357 pOut
->swizzleMode
= ADDR_SW_64KB_Z_X
;
2358 pOut
->resourceType
= ADDR_RSRC_TEX_2D
;
2359 pOut
->validBlockSet
.value
= AddrBlockSetMacro64KB
;
2360 pOut
->canXor
= TRUE
;
2361 pOut
->validSwTypeSet
.value
= AddrSwSetZ
;
2362 pOut
->clientPreferredSwSet
= pOut
->validSwTypeSet
;
2363 pOut
->validSwModeSet
.value
= Gfx10ZSwModeMask
;
2367 UINT_32 bpp
= pIn
->bpp
;
2368 UINT_32 width
= Max(pIn
->width
, 1u);
2369 UINT_32 height
= Max(pIn
->height
, 1u);
2371 // Set format to INVALID will skip this conversion
2372 if (pIn
->format
!= ADDR_FMT_INVALID
)
2374 ElemMode elemMode
= ADDR_UNCOMPRESSED
;
2375 UINT_32 expandX
, expandY
;
2377 // Get compression/expansion factors and element mode which indicates compression/expansion
2378 bpp
= GetElemLib()->GetBitsPerPixel(pIn
->format
,
2383 UINT_32 basePitch
= 0;
2384 GetElemLib()->AdjustSurfaceInfo(elemMode
,
2393 const UINT_32 numSlices
= Max(pIn
->numSlices
, 1u);
2394 const UINT_32 numMipLevels
= Max(pIn
->numMipLevels
, 1u);
2395 const UINT_32 numSamples
= Max(pIn
->numSamples
, 1u);
2396 const UINT_32 numFrags
= (pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
;
2397 const BOOL_32 msaa
= (numFrags
> 1) || (numSamples
> 1);
2399 // Pre sanity check on non swizzle mode parameters
2400 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {};
2401 localIn
.flags
= pIn
->flags
;
2402 localIn
.resourceType
= pIn
->resourceType
;
2403 localIn
.format
= pIn
->format
;
2405 localIn
.width
= width
;
2406 localIn
.height
= height
;
2407 localIn
.numSlices
= numSlices
;
2408 localIn
.numMipLevels
= numMipLevels
;
2409 localIn
.numSamples
= numSamples
;
2410 localIn
.numFrags
= numFrags
;
2412 if (ValidateNonSwModeParams(&localIn
))
2414 // Forbid swizzle mode(s) by client setting
2415 ADDR2_SWMODE_SET allowedSwModeSet
= {};
2416 allowedSwModeSet
.value
|= pIn
->forbiddenBlock
.linear
? 0 : Gfx10LinearSwModeMask
;
2417 allowedSwModeSet
.value
|= pIn
->forbiddenBlock
.micro
? 0 : Gfx10Blk256BSwModeMask
;
2418 allowedSwModeSet
.value
|= pIn
->forbiddenBlock
.macro4KB
? 0 : Gfx10Blk4KBSwModeMask
;
2419 allowedSwModeSet
.value
|= pIn
->forbiddenBlock
.macro64KB
? 0 : Gfx10Blk64KBSwModeMask
;
2421 if (pIn
->preferredSwSet
.value
!= 0)
2423 allowedSwModeSet
.value
&= pIn
->preferredSwSet
.sw_Z
? ~0 : ~Gfx10ZSwModeMask
;
2424 allowedSwModeSet
.value
&= pIn
->preferredSwSet
.sw_S
? ~0 : ~Gfx10StandardSwModeMask
;
2425 allowedSwModeSet
.value
&= pIn
->preferredSwSet
.sw_D
? ~0 : ~Gfx10DisplaySwModeMask
;
2426 allowedSwModeSet
.value
&= pIn
->preferredSwSet
.sw_R
? ~0 : ~Gfx10RenderSwModeMask
;
2431 allowedSwModeSet
.value
&= ~Gfx10XorSwModeMask
;
2434 if (pIn
->maxAlign
> 0)
2436 if (pIn
->maxAlign
< GetBlockSize(ADDR_SW_64KB
))
2438 allowedSwModeSet
.value
&= ~Gfx10Blk64KBSwModeMask
;
2441 if (pIn
->maxAlign
< GetBlockSize(ADDR_SW_4KB
))
2443 allowedSwModeSet
.value
&= ~Gfx10Blk4KBSwModeMask
;
2446 if (pIn
->maxAlign
< GetBlockSize(ADDR_SW_256B
))
2448 allowedSwModeSet
.value
&= ~Gfx10Blk256BSwModeMask
;
2452 // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
2453 switch (pIn
->resourceType
)
2455 case ADDR_RSRC_TEX_1D
:
2456 allowedSwModeSet
.value
&= Gfx10Rsrc1dSwModeMask
;
2459 case ADDR_RSRC_TEX_2D
:
2460 allowedSwModeSet
.value
&= pIn
->flags
.prt
? Gfx10Rsrc2dPrtSwModeMask
: Gfx10Rsrc2dSwModeMask
;
2463 case ADDR_RSRC_TEX_3D
:
2464 allowedSwModeSet
.value
&= pIn
->flags
.prt
? Gfx10Rsrc3dPrtSwModeMask
: Gfx10Rsrc3dSwModeMask
;
2466 if (m_settings
.supportRbPlus
)
2468 allowedSwModeSet
.value
&= ~Gfx10DisplaySwModeMask
;
2471 if (pIn
->flags
.view3dAs2dArray
)
2473 allowedSwModeSet
.value
&= Gfx10Rsrc3dThinSwModeMask
;
2478 ADDR_ASSERT_ALWAYS();
2479 allowedSwModeSet
.value
= 0;
2483 if (ElemLib::IsBlockCompressed(pIn
->format
) ||
2484 ElemLib::IsMacroPixelPacked(pIn
->format
) ||
2486 (msaa
&& ((bpp
> 32) || pIn
->flags
.color
|| pIn
->flags
.unordered
)))
2488 allowedSwModeSet
.value
&= ~Gfx10ZSwModeMask
;
2491 if (pIn
->format
== ADDR_FMT_32_32_32
)
2493 allowedSwModeSet
.value
&= Gfx10LinearSwModeMask
;
2498 allowedSwModeSet
.value
&= Gfx10MsaaSwModeMask
;
2501 if (pIn
->flags
.depth
|| pIn
->flags
.stencil
)
2503 allowedSwModeSet
.value
&= Gfx10ZSwModeMask
;
2506 if (pIn
->flags
.display
)
2508 if (m_settings
.isDcn2
)
2510 allowedSwModeSet
.value
&= (bpp
== 64) ? Dcn2Bpp64SwModeMask
: Dcn2NonBpp64SwModeMask
;
2514 ADDR_NOT_IMPLEMENTED();
2518 if (allowedSwModeSet
.value
!= 0)
2521 // Post sanity check, at least AddrLib should accept the output generated by its own
2522 UINT_32 validateSwModeSet
= allowedSwModeSet
.value
;
2524 for (UINT_32 i
= 0; validateSwModeSet
!= 0; i
++)
2526 if (validateSwModeSet
& 1)
2528 localIn
.swizzleMode
= static_cast<AddrSwizzleMode
>(i
);
2529 ADDR_ASSERT(ValidateSwModeParams(&localIn
));
2532 validateSwModeSet
>>= 1;
2536 pOut
->resourceType
= pIn
->resourceType
;
2537 pOut
->validSwModeSet
= allowedSwModeSet
;
2538 pOut
->canXor
= (allowedSwModeSet
.value
& Gfx10XorSwModeMask
) ? TRUE
: FALSE
;
2539 pOut
->validBlockSet
= GetAllowedBlockSet(allowedSwModeSet
);
2540 pOut
->validSwTypeSet
= GetAllowedSwSet(allowedSwModeSet
);
2542 pOut
->clientPreferredSwSet
= pIn
->preferredSwSet
;
2544 if (pOut
->clientPreferredSwSet
.value
== 0)
2546 pOut
->clientPreferredSwSet
.value
= AddrSwSetAll
;
2549 if (allowedSwModeSet
.value
== Gfx10LinearSwModeMask
)
2551 pOut
->swizzleMode
= ADDR_SW_LINEAR
;
2555 // Always ignore linear swizzle mode if there is other choice.
2556 allowedSwModeSet
.swLinear
= 0;
2558 ADDR2_BLOCK_SET allowedBlockSet
= GetAllowedBlockSet(allowedSwModeSet
);
2560 // Determine block size if there is 2 or more block type candidates
2561 if (IsPow2(allowedBlockSet
.value
) == FALSE
)
2563 const AddrSwizzleMode swMode
[AddrBlockMaxTiledType
] = {ADDR_SW_256B
, ADDR_SW_4KB
, ADDR_SW_64KB
};
2564 Dim3d blkDim
[AddrBlockMaxTiledType
] = {{0}, {0}, {0}};
2565 Dim3d padDim
[AddrBlockMaxTiledType
] = {{0}, {0}, {0}};
2566 UINT_64 padSize
[AddrBlockMaxTiledType
] = {0};
2568 const UINT_32 ratioLow
= pIn
->flags
.minimizeAlign
? 1 : (pIn
->flags
.opt4space
? 3 : 2);
2569 const UINT_32 ratioHi
= pIn
->flags
.minimizeAlign
? 1 : (pIn
->flags
.opt4space
? 2 : 1);
2570 const UINT_64 sizeAlignInElement
= Max(NextPow2(pIn
->minSizeAlign
) / (bpp
>> 3), 1u);
2571 UINT_32 minSizeBlk
= AddrBlockMicro
;
2572 UINT_64 minSize
= 0;
2574 for (UINT_32 i
= AddrBlockMicro
; i
< AddrBlockMaxTiledType
; i
++)
2576 if (allowedBlockSet
.value
& (1 << i
))
2578 ComputeBlockDimensionForSurf(&blkDim
[i
].w
,
2586 padSize
[i
] = ComputePadSize(&blkDim
[i
], width
, height
, numSlices
, &padDim
[i
]);
2587 padSize
[i
] = PowTwoAlign(padSize
[i
], sizeAlignInElement
);
2589 if ((minSize
== 0) ||
2590 ((padSize
[i
] * ratioHi
) <= (minSize
* ratioLow
)))
2592 minSize
= padSize
[i
];
2598 if ((allowedBlockSet
.micro
== TRUE
) &&
2599 (width
<= blkDim
[AddrBlockMicro
].w
) &&
2600 (height
<= blkDim
[AddrBlockMicro
].h
))
2602 minSizeBlk
= AddrBlockMicro
;
2605 if (minSizeBlk
== AddrBlockMicro
)
2607 allowedSwModeSet
.value
&= Gfx10Blk256BSwModeMask
;
2609 else if (minSizeBlk
== AddrBlock4KB
)
2611 allowedSwModeSet
.value
&= Gfx10Blk4KBSwModeMask
;
2615 ADDR_ASSERT(minSizeBlk
== AddrBlock64KB
);
2616 allowedSwModeSet
.value
&= Gfx10Blk64KBSwModeMask
;
2620 // Block type should be determined.
2621 ADDR_ASSERT(IsPow2(GetAllowedBlockSet(allowedSwModeSet
).value
));
2623 ADDR2_SWTYPE_SET allowedSwSet
= GetAllowedSwSet(allowedSwModeSet
);
2625 // Determine swizzle type if there is 2 or more swizzle type candidates
2626 if (IsPow2(allowedSwSet
.value
) == FALSE
)
2628 if (ElemLib::IsBlockCompressed(pIn
->format
))
2630 if (allowedSwSet
.sw_D
)
2632 allowedSwModeSet
.value
&= Gfx10DisplaySwModeMask
;
2634 else if (allowedSwSet
.sw_S
)
2636 allowedSwModeSet
.value
&= Gfx10StandardSwModeMask
;
2640 ADDR_ASSERT(allowedSwSet
.sw_R
);
2641 allowedSwModeSet
.value
&= Gfx10RenderSwModeMask
;
2644 else if (ElemLib::IsMacroPixelPacked(pIn
->format
))
2646 if (allowedSwSet
.sw_S
)
2648 allowedSwModeSet
.value
&= Gfx10StandardSwModeMask
;
2650 else if (allowedSwSet
.sw_D
)
2652 allowedSwModeSet
.value
&= Gfx10DisplaySwModeMask
;
2656 ADDR_ASSERT(allowedSwSet
.sw_R
);
2657 allowedSwModeSet
.value
&= Gfx10RenderSwModeMask
;
2660 else if (pIn
->resourceType
== ADDR_RSRC_TEX_3D
)
2662 if (pIn
->flags
.color
&& GetAllowedBlockSet(allowedSwModeSet
).macro64KB
&& allowedSwSet
.sw_D
)
2664 allowedSwModeSet
.value
&= Gfx10DisplaySwModeMask
;
2666 else if (allowedSwSet
.sw_S
)
2668 allowedSwModeSet
.value
&= Gfx10StandardSwModeMask
;
2670 else if (allowedSwSet
.sw_R
)
2672 allowedSwModeSet
.value
&= Gfx10RenderSwModeMask
;
2676 ADDR_ASSERT(allowedSwSet
.sw_Z
);
2677 allowedSwModeSet
.value
&= Gfx10ZSwModeMask
;
2682 if (allowedSwSet
.sw_R
)
2684 allowedSwModeSet
.value
&= Gfx10RenderSwModeMask
;
2686 else if (allowedSwSet
.sw_D
)
2688 allowedSwModeSet
.value
&= Gfx10DisplaySwModeMask
;
2690 else if (allowedSwSet
.sw_S
)
2692 allowedSwModeSet
.value
&= Gfx10StandardSwModeMask
;
2696 ADDR_ASSERT(allowedSwSet
.sw_Z
);
2697 allowedSwModeSet
.value
&= Gfx10ZSwModeMask
;
2702 // Swizzle type should be determined.
2703 ADDR_ASSERT(IsPow2(GetAllowedSwSet(allowedSwModeSet
).value
));
2705 // Determine swizzle mode now - always select the "largest" swizzle mode for a given block type +
2706 // swizzle type combination. For example, for AddrBlock64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's
2707 // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).
2708 pOut
->swizzleMode
= static_cast<AddrSwizzleMode
>(Log2NonPow2(allowedSwModeSet
.value
));
2713 // Invalid combination...
2714 ADDR_ASSERT_ALWAYS();
2715 returnCode
= ADDR_INVALIDPARAMS
;
2720 // Invalid combination...
2721 ADDR_ASSERT_ALWAYS();
2722 returnCode
= ADDR_INVALIDPARAMS
;
2730 ************************************************************************************************************************
2731 * Gfx10Lib::ComputeStereoInfo
2734 * Compute height alignment and right eye pipeBankXor for stereo surface
2739 ************************************************************************************************************************
2741 ADDR_E_RETURNCODE
Gfx10Lib::ComputeStereoInfo(
2742 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< Compute surface info
2743 UINT_32 blkHeight
, ///< Block height
2744 UINT_32
* pAlignY
, ///< Stereo requested additional alignment in Y
2745 UINT_32
* pRightXor
///< Right eye xor
2748 ADDR_E_RETURNCODE ret
= ADDR_OK
;
2753 if (IsNonPrtXor(pIn
->swizzleMode
))
2755 const UINT_32 blkSizeLog2
= GetBlockSizeLog2(pIn
->swizzleMode
);
2756 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
2757 const UINT_32 rsrcType
= static_cast<UINT_32
>(pIn
->resourceType
) - 1;
2758 const UINT_32 swMode
= static_cast<UINT_32
>(pIn
->swizzleMode
);
2759 const UINT_32 eqIndex
= m_equationLookupTable
[rsrcType
][swMode
][elemLog2
];
2761 if (eqIndex
!= ADDR_INVALID_EQUATION_INDEX
)
2766 for (UINT_32 i
= m_pipeInterleaveLog2
; i
< blkSizeLog2
; i
++)
2768 if (m_equationTable
[eqIndex
].xor1
[i
].value
== 0)
2773 ADDR_ASSERT(m_equationTable
[eqIndex
].xor1
[i
].valid
== 1);
2775 if ((m_equationTable
[eqIndex
].xor1
[i
].channel
== 1) &&
2776 (m_equationTable
[eqIndex
].xor1
[i
].index
> yMax
))
2778 yMax
= m_equationTable
[eqIndex
].xor1
[i
].index
;
2783 const UINT_32 additionalAlign
= 1 << yMax
;
2785 if (additionalAlign
>= blkHeight
)
2787 *pAlignY
*= (additionalAlign
/ blkHeight
);
2789 const UINT_32 alignedHeight
= PowTwoAlign(pIn
->height
, additionalAlign
);
2791 if ((alignedHeight
>> yMax
) & 1)
2793 *pRightXor
= 1 << (yPos
- m_pipeInterleaveLog2
);
2799 ret
= ADDR_INVALIDPARAMS
;
2807 ************************************************************************************************************************
2808 * Gfx10Lib::HwlComputeSurfaceInfoTiled
2811 * Internal function to calculate alignment for tiled surface
2815 ************************************************************************************************************************
2817 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSurfaceInfoTiled(
2818 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2819 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
2822 ADDR_E_RETURNCODE ret
;
2824 if (IsBlock256b(pIn
->swizzleMode
))
2826 ret
= ComputeSurfaceInfoMicroTiled(pIn
, pOut
);
2830 ret
= ComputeSurfaceInfoMacroTiled(pIn
, pOut
);
2837 ************************************************************************************************************************
2838 * Gfx10Lib::ComputeSurfaceInfoMicroTiled
2841 * Internal function to calculate alignment for micro tiled surface
2845 ************************************************************************************************************************
2847 ADDR_E_RETURNCODE
Gfx10Lib::ComputeSurfaceInfoMicroTiled(
2848 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2849 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
2852 ADDR_E_RETURNCODE ret
= ComputeBlockDimensionForSurf(&pOut
->blockWidth
,
2862 pOut
->mipChainPitch
= 0;
2863 pOut
->mipChainHeight
= 0;
2864 pOut
->mipChainSlice
= 0;
2865 pOut
->epitchIsHeight
= FALSE
;
2866 pOut
->mipChainInTail
= FALSE
;
2867 pOut
->firstMipIdInTail
= pIn
->numMipLevels
;
2869 const UINT_32 blockSize
= GetBlockSize(pIn
->swizzleMode
);
2871 pOut
->pitch
= PowTwoAlign(pIn
->width
, pOut
->blockWidth
);
2872 pOut
->height
= PowTwoAlign(pIn
->height
, pOut
->blockHeight
);
2873 pOut
->numSlices
= pIn
->numSlices
;
2874 pOut
->baseAlign
= blockSize
;
2876 if (pIn
->numMipLevels
> 1)
2878 const UINT_32 mip0Width
= pIn
->width
;
2879 const UINT_32 mip0Height
= pIn
->height
;
2880 UINT_64 mipSliceSize
= 0;
2882 for (INT_32 i
= static_cast<INT_32
>(pIn
->numMipLevels
) - 1; i
>= 0; i
--)
2884 UINT_32 mipWidth
, mipHeight
;
2886 GetMipSize(mip0Width
, mip0Height
, 1, i
, &mipWidth
, &mipHeight
);
2888 const UINT_32 mipActualWidth
= PowTwoAlign(mipWidth
, pOut
->blockWidth
);
2889 const UINT_32 mipActualHeight
= PowTwoAlign(mipHeight
, pOut
->blockHeight
);
2891 if (pOut
->pMipInfo
!= NULL
)
2893 pOut
->pMipInfo
[i
].pitch
= mipActualWidth
;
2894 pOut
->pMipInfo
[i
].height
= mipActualHeight
;
2895 pOut
->pMipInfo
[i
].depth
= 1;
2896 pOut
->pMipInfo
[i
].offset
= mipSliceSize
;
2897 pOut
->pMipInfo
[i
].mipTailOffset
= 0;
2898 pOut
->pMipInfo
[i
].macroBlockOffset
= mipSliceSize
;
2901 mipSliceSize
+= mipActualWidth
* mipActualHeight
* (pIn
->bpp
>> 3);
2904 pOut
->sliceSize
= mipSliceSize
;
2905 pOut
->surfSize
= mipSliceSize
* pOut
->numSlices
;
2909 pOut
->sliceSize
= static_cast<UINT_64
>(pOut
->pitch
) * pOut
->height
* (pIn
->bpp
>> 3);
2910 pOut
->surfSize
= pOut
->sliceSize
* pOut
->numSlices
;
2912 if (pOut
->pMipInfo
!= NULL
)
2914 pOut
->pMipInfo
[0].pitch
= pOut
->pitch
;
2915 pOut
->pMipInfo
[0].height
= pOut
->height
;
2916 pOut
->pMipInfo
[0].depth
= 1;
2917 pOut
->pMipInfo
[0].offset
= 0;
2918 pOut
->pMipInfo
[0].mipTailOffset
= 0;
2919 pOut
->pMipInfo
[0].macroBlockOffset
= 0;
2929 ************************************************************************************************************************
2930 * Gfx10Lib::ComputeSurfaceInfoMacroTiled
2933 * Internal function to calculate alignment for macro tiled surface
2937 ************************************************************************************************************************
2939 ADDR_E_RETURNCODE
Gfx10Lib::ComputeSurfaceInfoMacroTiled(
2940 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2941 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
2944 ADDR_E_RETURNCODE returnCode
= ComputeBlockDimensionForSurf(&pOut
->blockWidth
,
2952 if (returnCode
== ADDR_OK
)
2954 UINT_32 heightAlign
= pOut
->blockHeight
;
2956 if (pIn
->flags
.qbStereo
)
2958 UINT_32 rightXor
= 0;
2961 returnCode
= ComputeStereoInfo(pIn
, heightAlign
, &alignY
, &rightXor
);
2963 if (returnCode
== ADDR_OK
)
2965 pOut
->pStereoInfo
->rightSwizzle
= rightXor
;
2967 heightAlign
*= alignY
;
2971 if (returnCode
== ADDR_OK
)
2973 // Mip chain dimesion and epitch has no meaning in GFX10, set to default value
2974 pOut
->mipChainPitch
= 0;
2975 pOut
->mipChainHeight
= 0;
2976 pOut
->mipChainSlice
= 0;
2977 pOut
->epitchIsHeight
= FALSE
;
2978 pOut
->mipChainInTail
= FALSE
;
2979 pOut
->firstMipIdInTail
= pIn
->numMipLevels
;
2981 const UINT_32 blockSizeLog2
= GetBlockSizeLog2(pIn
->swizzleMode
);
2982 const UINT_32 blockSize
= 1 << blockSizeLog2
;
2984 pOut
->pitch
= PowTwoAlign(pIn
->width
, pOut
->blockWidth
);
2985 pOut
->height
= PowTwoAlign(pIn
->height
, heightAlign
);
2986 pOut
->numSlices
= PowTwoAlign(pIn
->numSlices
, pOut
->blockSlices
);
2987 pOut
->baseAlign
= blockSize
;
2989 if (pIn
->numMipLevels
> 1)
2991 const Dim3d tailMaxDim
= GetMipTailDim(pIn
->resourceType
,
2996 const UINT_32 mip0Width
= pIn
->width
;
2997 const UINT_32 mip0Height
= pIn
->height
;
2998 const BOOL_32 isThin
= IsThin(pIn
->resourceType
, pIn
->swizzleMode
);
2999 const UINT_32 mip0Depth
= isThin
? 1 : pIn
->numSlices
;
3000 const UINT_32 maxMipsInTail
= GetMaxNumMipsInTail(blockSizeLog2
, isThin
);
3001 const UINT_32 index
= Log2(pIn
->bpp
>> 3);
3002 UINT_32 firstMipInTail
= pIn
->numMipLevels
;
3003 UINT_64 mipChainSliceSize
= 0;
3004 UINT_64 mipSize
[MaxMipLevels
];
3005 UINT_64 mipSliceSize
[MaxMipLevels
];
3007 Dim3d fixedTailMaxDim
= tailMaxDim
;
3009 if (m_settings
.dsMipmapHtileFix
&& IsZOrderSwizzle(pIn
->swizzleMode
) && (index
<= 1))
3011 fixedTailMaxDim
.w
/= Block256_2d
[index
].w
/ Block256_2d
[2].w
;
3012 fixedTailMaxDim
.h
/= Block256_2d
[index
].h
/ Block256_2d
[2].h
;
3015 for (UINT_32 i
= 0; i
< pIn
->numMipLevels
; i
++)
3017 UINT_32 mipWidth
, mipHeight
, mipDepth
;
3019 GetMipSize(mip0Width
, mip0Height
, mip0Depth
, i
, &mipWidth
, &mipHeight
, &mipDepth
);
3021 if (IsInMipTail(fixedTailMaxDim
, maxMipsInTail
, mipWidth
, mipHeight
, pIn
->numMipLevels
- i
))
3024 mipChainSliceSize
+= blockSize
/ pOut
->blockSlices
;
3029 const UINT_32 pitch
= PowTwoAlign(mipWidth
, pOut
->blockWidth
);
3030 const UINT_32 height
= PowTwoAlign(mipHeight
, pOut
->blockHeight
);
3031 const UINT_32 depth
= PowTwoAlign(mipDepth
, pOut
->blockSlices
);
3032 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
* (pIn
->bpp
>> 3);
3034 mipSize
[i
] = sliceSize
* depth
;
3035 mipSliceSize
[i
] = sliceSize
* pOut
->blockSlices
;
3036 mipChainSliceSize
+= sliceSize
;
3038 if (pOut
->pMipInfo
!= NULL
)
3040 pOut
->pMipInfo
[i
].pitch
= pitch
;
3041 pOut
->pMipInfo
[i
].height
= height
;
3042 pOut
->pMipInfo
[i
].depth
= depth
;
3047 pOut
->sliceSize
= mipChainSliceSize
;
3048 pOut
->surfSize
= mipChainSliceSize
* pOut
->numSlices
;
3049 pOut
->mipChainInTail
= (firstMipInTail
== 0) ? TRUE
: FALSE
;
3050 pOut
->firstMipIdInTail
= firstMipInTail
;
3052 if (pOut
->pMipInfo
!= NULL
)
3055 UINT_64 macroBlkOffset
= 0;
3056 UINT_32 tailMaxDepth
= 0;
3058 if (firstMipInTail
!= pIn
->numMipLevels
)
3060 UINT_32 mipWidth
, mipHeight
;
3062 GetMipSize(mip0Width
, mip0Height
, mip0Depth
, firstMipInTail
,
3063 &mipWidth
, &mipHeight
, &tailMaxDepth
);
3065 offset
= blockSize
* PowTwoAlign(tailMaxDepth
, pOut
->blockSlices
) / pOut
->blockSlices
;
3066 macroBlkOffset
= blockSize
;
3069 for (INT_32 i
= firstMipInTail
- 1; i
>= 0; i
--)
3071 pOut
->pMipInfo
[i
].offset
= offset
;
3072 pOut
->pMipInfo
[i
].macroBlockOffset
= macroBlkOffset
;
3073 pOut
->pMipInfo
[i
].mipTailOffset
= 0;
3075 offset
+= mipSize
[i
];
3076 macroBlkOffset
+= mipSliceSize
[i
];
3079 UINT_32 pitch
= tailMaxDim
.w
;
3080 UINT_32 height
= tailMaxDim
.h
;
3081 UINT_32 depth
= isThin
? 1 : PowTwoAlign(tailMaxDepth
, Block256_3d
[index
].d
);
3083 tailMaxDepth
= isThin
? 1 : (depth
/ Block256_3d
[index
].d
);
3085 for (UINT_32 i
= firstMipInTail
; i
< pIn
->numMipLevels
; i
++)
3087 const UINT_32 m
= maxMipsInTail
- 1 - (i
- firstMipInTail
);
3088 const UINT_32 mipOffset
= (m
> 6) ? (16 << m
) : (m
<< 8);
3090 pOut
->pMipInfo
[i
].offset
= mipOffset
* tailMaxDepth
;
3091 pOut
->pMipInfo
[i
].mipTailOffset
= mipOffset
;
3092 pOut
->pMipInfo
[i
].macroBlockOffset
= 0;
3094 pOut
->pMipInfo
[i
].pitch
= pitch
;
3095 pOut
->pMipInfo
[i
].height
= height
;
3096 pOut
->pMipInfo
[i
].depth
= depth
;
3098 UINT_32 mipX
= ((mipOffset
>> 9) & 1) |
3099 ((mipOffset
>> 10) & 2) |
3100 ((mipOffset
>> 11) & 4) |
3101 ((mipOffset
>> 12) & 8) |
3102 ((mipOffset
>> 13) & 16) |
3103 ((mipOffset
>> 14) & 32);
3104 UINT_32 mipY
= ((mipOffset
>> 8) & 1) |
3105 ((mipOffset
>> 9) & 2) |
3106 ((mipOffset
>> 10) & 4) |
3107 ((mipOffset
>> 11) & 8) |
3108 ((mipOffset
>> 12) & 16) |
3109 ((mipOffset
>> 13) & 32);
3111 if (blockSizeLog2
& 1)
3113 const UINT_32 temp
= mipX
;
3119 mipY
= (mipY
<< 1) | (mipX
& 1);
3126 pOut
->pMipInfo
[i
].mipTailCoordX
= mipX
* Block256_2d
[index
].w
;
3127 pOut
->pMipInfo
[i
].mipTailCoordY
= mipY
* Block256_2d
[index
].h
;
3128 pOut
->pMipInfo
[i
].mipTailCoordZ
= 0;
3130 pitch
= Max(pitch
>> 1, Block256_2d
[index
].w
);
3131 height
= Max(height
>> 1, Block256_2d
[index
].h
);
3136 pOut
->pMipInfo
[i
].mipTailCoordX
= mipX
* Block256_3d
[index
].w
;
3137 pOut
->pMipInfo
[i
].mipTailCoordY
= mipY
* Block256_3d
[index
].h
;
3138 pOut
->pMipInfo
[i
].mipTailCoordZ
= 0;
3140 pitch
= Max(pitch
>> 1, Block256_3d
[index
].w
);
3141 height
= Max(height
>> 1, Block256_3d
[index
].h
);
3142 depth
= PowTwoAlign(Max(depth
>> 1, 1u), Block256_3d
[index
].d
);
3149 pOut
->sliceSize
= static_cast<UINT_64
>(pOut
->pitch
) * pOut
->height
* (pIn
->bpp
>> 3) * pIn
->numFrags
;
3150 pOut
->surfSize
= pOut
->sliceSize
* pOut
->numSlices
;
3152 if (pOut
->pMipInfo
!= NULL
)
3154 pOut
->pMipInfo
[0].pitch
= pOut
->pitch
;
3155 pOut
->pMipInfo
[0].height
= pOut
->height
;
3156 pOut
->pMipInfo
[0].depth
= IsTex3d(pIn
->resourceType
)? pOut
->numSlices
: 1;
3157 pOut
->pMipInfo
[0].offset
= 0;
3158 pOut
->pMipInfo
[0].mipTailOffset
= 0;
3159 pOut
->pMipInfo
[0].macroBlockOffset
= 0;
3160 pOut
->pMipInfo
[0].mipTailCoordX
= 0;
3161 pOut
->pMipInfo
[0].mipTailCoordY
= 0;
3162 pOut
->pMipInfo
[0].mipTailCoordZ
= 0;
3172 ************************************************************************************************************************
3173 * Gfx10Lib::HwlComputeSurfaceAddrFromCoordTiled
3176 * Internal function to calculate address from coord for tiled swizzle surface
3180 ************************************************************************************************************************
3182 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSurfaceAddrFromCoordTiled(
3183 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3184 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3187 ADDR_E_RETURNCODE ret
;
3189 if (IsBlock256b(pIn
->swizzleMode
))
3191 ret
= ComputeSurfaceAddrFromCoordMicroTiled(pIn
, pOut
);
3195 ret
= ComputeSurfaceAddrFromCoordMacroTiled(pIn
, pOut
);
3202 ************************************************************************************************************************
3203 * Gfx10Lib::ComputeOffsetFromEquation
3206 * Compute offset from equation
3210 ************************************************************************************************************************
3212 UINT_32
Gfx10Lib::ComputeOffsetFromEquation(
3213 const ADDR_EQUATION
* pEq
, ///< Equation
3214 UINT_32 x
, ///< x coord in bytes
3215 UINT_32 y
, ///< y coord in pixel
3216 UINT_32 z
///< z coord in slice
3221 for (UINT_32 i
= 0; i
< pEq
->numBits
; i
++)
3225 if (pEq
->addr
[i
].valid
)
3227 if (pEq
->addr
[i
].channel
== 0)
3229 v
^= (x
>> pEq
->addr
[i
].index
) & 1;
3231 else if (pEq
->addr
[i
].channel
== 1)
3233 v
^= (y
>> pEq
->addr
[i
].index
) & 1;
3237 ADDR_ASSERT(pEq
->addr
[i
].channel
== 2);
3238 v
^= (z
>> pEq
->addr
[i
].index
) & 1;
3242 if (pEq
->xor1
[i
].valid
)
3244 if (pEq
->xor1
[i
].channel
== 0)
3246 v
^= (x
>> pEq
->xor1
[i
].index
) & 1;
3248 else if (pEq
->xor1
[i
].channel
== 1)
3250 v
^= (y
>> pEq
->xor1
[i
].index
) & 1;
3254 ADDR_ASSERT(pEq
->xor1
[i
].channel
== 2);
3255 v
^= (z
>> pEq
->xor1
[i
].index
) & 1;
3259 if (pEq
->xor2
[i
].valid
)
3261 if (pEq
->xor2
[i
].channel
== 0)
3263 v
^= (x
>> pEq
->xor2
[i
].index
) & 1;
3265 else if (pEq
->xor2
[i
].channel
== 1)
3267 v
^= (y
>> pEq
->xor2
[i
].index
) & 1;
3271 ADDR_ASSERT(pEq
->xor2
[i
].channel
== 2);
3272 v
^= (z
>> pEq
->xor2
[i
].index
) & 1;
3283 ************************************************************************************************************************
3284 * Gfx10Lib::ComputeOffsetFromSwizzlePattern
3287 * Compute offset from swizzle pattern
3291 ************************************************************************************************************************
3293 UINT_32
Gfx10Lib::ComputeOffsetFromSwizzlePattern(
3294 const UINT_64
* pPattern
, ///< Swizzle pattern
3295 UINT_32 numBits
, ///< Number of bits in pattern
3296 UINT_32 x
, ///< x coord in pixel
3297 UINT_32 y
, ///< y coord in pixel
3298 UINT_32 z
, ///< z coord in slice
3299 UINT_32 s
///< sample id
3303 const ADDR_BIT_SETTING
* pSwizzlePattern
= reinterpret_cast<const ADDR_BIT_SETTING
*>(pPattern
);
3305 for (UINT_32 i
= 0; i
< numBits
; i
++)
3309 if (pSwizzlePattern
[i
].x
!= 0)
3311 UINT_16 mask
= pSwizzlePattern
[i
].x
;
3326 if (pSwizzlePattern
[i
].y
!= 0)
3328 UINT_16 mask
= pSwizzlePattern
[i
].y
;
3343 if (pSwizzlePattern
[i
].z
!= 0)
3345 UINT_16 mask
= pSwizzlePattern
[i
].z
;
3360 if (pSwizzlePattern
[i
].s
!= 0)
3362 UINT_16 mask
= pSwizzlePattern
[i
].s
;
3384 ************************************************************************************************************************
3385 * Gfx10Lib::GetSwizzlePattern
3388 * Get swizzle pattern
3392 ************************************************************************************************************************
3394 const UINT_64
* Gfx10Lib::GetSwizzlePattern(
3395 AddrSwizzleMode swizzleMode
, ///< Swizzle mode
3396 AddrResourceType resourceType
, ///< Resource type
3397 UINT_32 elemLog2
, ///< Element size in bytes log2
3398 UINT_32 numFrag
///< Number of fragment
3401 const UINT_32 index
= IsXor(swizzleMode
) ? (m_colorBaseIndex
+ elemLog2
) : elemLog2
;
3402 const UINT_64
* pSwizzlePattern
= NULL
;
3403 const UINT_32 swizzleMask
= 1 << swizzleMode
;
3405 if (IsLinear(swizzleMode
))
3407 pSwizzlePattern
= NULL
;
3409 else if (resourceType
== ADDR_RSRC_TEX_3D
)
3411 ADDR_ASSERT(numFrag
== 1);
3413 if ((swizzleMask
& Gfx10Rsrc3dSwModeMask
) == 0)
3415 pSwizzlePattern
= NULL
;
3417 else if (IsRtOptSwizzle(swizzleMode
))
3419 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_R_X_1xaa_RBPLUS
[index
] : SW_64K_R_X_1xaa
[index
];
3421 else if (IsZOrderSwizzle(swizzleMode
))
3423 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_Z_X_1xaa_RBPLUS
[index
] : SW_64K_Z_X_1xaa
[index
];
3425 else if (IsDisplaySwizzle(resourceType
, swizzleMode
))
3427 ADDR_ASSERT(swizzleMode
== ADDR_SW_64KB_D_X
);
3428 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_D3_X_RBPLUS
[index
] : SW_64K_D3_X
[index
];
3432 ADDR_ASSERT(IsStandardSwizzle(resourceType
, swizzleMode
));
3434 if (IsBlock4kb(swizzleMode
))
3436 if (swizzleMode
== ADDR_SW_4KB_S
)
3438 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_S3_RBPLUS
[index
] : SW_4K_S3
[index
];
3442 ADDR_ASSERT(swizzleMode
== ADDR_SW_4KB_S_X
);
3443 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_S3_X_RBPLUS
[index
] : SW_4K_S3_X
[index
];
3448 if (swizzleMode
== ADDR_SW_64KB_S
)
3450 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S3_RBPLUS
[index
] : SW_64K_S3
[index
];
3452 else if (swizzleMode
== ADDR_SW_64KB_S_X
)
3454 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S3_X_RBPLUS
[index
] : SW_64K_S3_X
[index
];
3458 ADDR_ASSERT(swizzleMode
== ADDR_SW_64KB_S_T
);
3459 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S3_T_RBPLUS
[index
] : SW_64K_S3_T
[index
];
3467 if ((swizzleMask
& Gfx10Rsrc2dSwModeMask
) == 0)
3469 pSwizzlePattern
= NULL
;
3471 else if (IsBlock256b(swizzleMode
))
3473 if (swizzleMode
== ADDR_SW_256B_S
)
3475 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_256_S_RBPLUS
[index
] : SW_256_S
[index
];
3479 ADDR_ASSERT(swizzleMode
== ADDR_SW_256B_D
);
3480 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_256_D_RBPLUS
[index
] : SW_256_D
[index
];
3483 else if (IsBlock4kb(swizzleMode
))
3485 if (IsStandardSwizzle(resourceType
, swizzleMode
))
3487 if (swizzleMode
== ADDR_SW_4KB_S
)
3489 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_S_RBPLUS
[index
] : SW_4K_S
[index
];
3493 ADDR_ASSERT(swizzleMode
== ADDR_SW_4KB_S_X
);
3494 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_S_X_RBPLUS
[index
] : SW_4K_S_X
[index
];
3499 if (swizzleMode
== ADDR_SW_4KB_D
)
3501 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_D_RBPLUS
[index
] : SW_4K_D
[index
];
3505 ADDR_ASSERT(swizzleMode
== ADDR_SW_4KB_D_X
);
3506 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_D_X_RBPLUS
[index
] : SW_4K_D_X
[index
];
3512 if (IsRtOptSwizzle(swizzleMode
))
3516 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_R_X_1xaa_RBPLUS
[index
] : SW_64K_R_X_1xaa
[index
];
3518 else if (numFrag
== 2)
3520 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_R_X_2xaa_RBPLUS
[index
] : SW_64K_R_X_2xaa
[index
];
3522 else if (numFrag
== 4)
3524 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_R_X_4xaa_RBPLUS
[index
] : SW_64K_R_X_4xaa
[index
];
3528 ADDR_ASSERT(numFrag
== 8);
3529 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_R_X_8xaa_RBPLUS
[index
] : SW_64K_R_X_8xaa
[index
];
3532 else if (IsZOrderSwizzle(swizzleMode
))
3536 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_Z_X_1xaa_RBPLUS
[index
] : SW_64K_Z_X_1xaa
[index
];
3538 else if (numFrag
== 2)
3540 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_Z_X_2xaa_RBPLUS
[index
] : SW_64K_Z_X_2xaa
[index
];
3542 else if (numFrag
== 4)
3544 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_Z_X_4xaa_RBPLUS
[index
] : SW_64K_Z_X_4xaa
[index
];
3548 ADDR_ASSERT(numFrag
== 8);
3549 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_Z_X_8xaa_RBPLUS
[index
] : SW_64K_Z_X_8xaa
[index
];
3552 else if (IsDisplaySwizzle(resourceType
, swizzleMode
))
3554 if (swizzleMode
== ADDR_SW_64KB_D
)
3556 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_D_RBPLUS
[index
] : SW_64K_D
[index
];
3558 else if (swizzleMode
== ADDR_SW_64KB_D_X
)
3560 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_D_X_RBPLUS
[index
] : SW_64K_D_X
[index
];
3564 ADDR_ASSERT(swizzleMode
== ADDR_SW_64KB_D_T
);
3565 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_D_T_RBPLUS
[index
] : SW_64K_D_T
[index
];
3570 if (swizzleMode
== ADDR_SW_64KB_S
)
3572 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S_RBPLUS
[index
] : SW_64K_S
[index
];
3574 else if (swizzleMode
== ADDR_SW_64KB_S_X
)
3576 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S_X_RBPLUS
[index
] : SW_64K_S_X
[index
];
3580 ADDR_ASSERT(swizzleMode
== ADDR_SW_64KB_S_T
);
3581 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S_T_RBPLUS
[index
] : SW_64K_S_T
[index
];
3587 return pSwizzlePattern
;
3591 ************************************************************************************************************************
3592 * Gfx10Lib::ComputeSurfaceAddrFromCoordMicroTiled
3595 * Internal function to calculate address from coord for micro tiled swizzle surface
3599 ************************************************************************************************************************
3601 ADDR_E_RETURNCODE
Gfx10Lib::ComputeSurfaceAddrFromCoordMicroTiled(
3602 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3603 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3606 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {0};
3607 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut
= {0};
3608 ADDR2_MIP_INFO mipInfo
[MaxMipLevels
];
3610 localIn
.swizzleMode
= pIn
->swizzleMode
;
3611 localIn
.flags
= pIn
->flags
;
3612 localIn
.resourceType
= pIn
->resourceType
;
3613 localIn
.bpp
= pIn
->bpp
;
3614 localIn
.width
= Max(pIn
->unalignedWidth
, 1u);
3615 localIn
.height
= Max(pIn
->unalignedHeight
, 1u);
3616 localIn
.numSlices
= Max(pIn
->numSlices
, 1u);
3617 localIn
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
3618 localIn
.numSamples
= Max(pIn
->numSamples
, 1u);
3619 localIn
.numFrags
= Max(pIn
->numFrags
, 1u);
3620 localOut
.pMipInfo
= mipInfo
;
3622 ADDR_E_RETURNCODE ret
= ComputeSurfaceInfoMicroTiled(&localIn
, &localOut
);
3626 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
3627 const UINT_32 rsrcType
= static_cast<UINT_32
>(pIn
->resourceType
) - 1;
3628 const UINT_32 swMode
= static_cast<UINT_32
>(pIn
->swizzleMode
);
3629 const UINT_32 eqIndex
= m_equationLookupTable
[rsrcType
][swMode
][elemLog2
];
3631 if (eqIndex
!= ADDR_INVALID_EQUATION_INDEX
)
3633 const UINT_32 pb
= mipInfo
[pIn
->mipId
].pitch
/ localOut
.blockWidth
;
3634 const UINT_32 yb
= pIn
->y
/ localOut
.blockHeight
;
3635 const UINT_32 xb
= pIn
->x
/ localOut
.blockWidth
;
3636 const UINT_32 blockIndex
= yb
* pb
+ xb
;
3637 const UINT_32 blockSize
= 256;
3638 const UINT_32 blk256Offset
= ComputeOffsetFromEquation(&m_equationTable
[eqIndex
],
3642 pOut
->addr
= localOut
.sliceSize
* pIn
->slice
+
3643 mipInfo
[pIn
->mipId
].macroBlockOffset
+
3644 (blockIndex
* blockSize
) +
3649 ret
= ADDR_INVALIDPARAMS
;
3657 ************************************************************************************************************************
3658 * Gfx10Lib::ComputeSurfaceAddrFromCoordMacroTiled
3661 * Internal function to calculate address from coord for macro tiled swizzle surface
3665 ************************************************************************************************************************
3667 ADDR_E_RETURNCODE
Gfx10Lib::ComputeSurfaceAddrFromCoordMacroTiled(
3668 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3669 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3672 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {0};
3673 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut
= {0};
3674 ADDR2_MIP_INFO mipInfo
[MaxMipLevels
];
3676 localIn
.swizzleMode
= pIn
->swizzleMode
;
3677 localIn
.flags
= pIn
->flags
;
3678 localIn
.resourceType
= pIn
->resourceType
;
3679 localIn
.bpp
= pIn
->bpp
;
3680 localIn
.width
= Max(pIn
->unalignedWidth
, 1u);
3681 localIn
.height
= Max(pIn
->unalignedHeight
, 1u);
3682 localIn
.numSlices
= Max(pIn
->numSlices
, 1u);
3683 localIn
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
3684 localIn
.numSamples
= Max(pIn
->numSamples
, 1u);
3685 localIn
.numFrags
= Max(pIn
->numFrags
, 1u);
3686 localOut
.pMipInfo
= mipInfo
;
3688 ADDR_E_RETURNCODE ret
= ComputeSurfaceInfoMacroTiled(&localIn
, &localOut
);
3692 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
3693 const UINT_32 blkSizeLog2
= GetBlockSizeLog2(pIn
->swizzleMode
);
3694 const UINT_32 blkMask
= (1 << blkSizeLog2
) - 1;
3695 const UINT_32 pipeMask
= (1 << m_pipesLog2
) - 1;
3696 const UINT_32 bankMask
= ((1 << GetBankXorBits(blkSizeLog2
)) - 1) << (m_pipesLog2
+ ColumnBits
);
3697 const UINT_32 pipeBankXor
= IsXor(pIn
->swizzleMode
) ?
3698 (((pIn
->pipeBankXor
& (pipeMask
| bankMask
)) << m_pipeInterleaveLog2
) & blkMask
) : 0;
3700 if (localIn
.numFrags
> 1)
3702 const UINT_64
* pPattern
= GetSwizzlePattern(pIn
->swizzleMode
,
3707 if (pPattern
!= NULL
)
3709 const UINT_32 pb
= localOut
.pitch
/ localOut
.blockWidth
;
3710 const UINT_32 yb
= pIn
->y
/ localOut
.blockHeight
;
3711 const UINT_32 xb
= pIn
->x
/ localOut
.blockWidth
;
3712 const UINT_64 blkIdx
= yb
* pb
+ xb
;
3713 const UINT_32 blkOffset
= ComputeOffsetFromSwizzlePattern(pPattern
,
3719 pOut
->addr
= (localOut
.sliceSize
* pIn
->slice
) +
3720 (blkIdx
<< blkSizeLog2
) +
3721 (blkOffset
^ pipeBankXor
);
3725 ret
= ADDR_INVALIDPARAMS
;
3730 const UINT_32 rsrcIdx
= (pIn
->resourceType
== ADDR_RSRC_TEX_3D
) ? 1 : 0;
3731 const UINT_32 swMode
= static_cast<UINT_32
>(pIn
->swizzleMode
);
3732 const UINT_32 eqIndex
= m_equationLookupTable
[rsrcIdx
][swMode
][elemLog2
];
3734 if (eqIndex
!= ADDR_INVALID_EQUATION_INDEX
)
3736 const BOOL_32 inTail
= (mipInfo
[pIn
->mipId
].mipTailOffset
!= 0) ? TRUE
: FALSE
;
3737 const BOOL_32 isThin
= IsThin(pIn
->resourceType
, pIn
->swizzleMode
);
3738 const UINT_64 sliceSize
= isThin
? localOut
.sliceSize
: (localOut
.sliceSize
* localOut
.blockSlices
);
3739 const UINT_32 sliceId
= isThin
? pIn
->slice
: (pIn
->slice
/ localOut
.blockSlices
);
3740 const UINT_32 x
= inTail
? (pIn
->x
+ mipInfo
[pIn
->mipId
].mipTailCoordX
) : pIn
->x
;
3741 const UINT_32 y
= inTail
? (pIn
->y
+ mipInfo
[pIn
->mipId
].mipTailCoordY
) : pIn
->y
;
3742 const UINT_32 z
= inTail
? (pIn
->slice
+ mipInfo
[pIn
->mipId
].mipTailCoordZ
) : pIn
->slice
;
3743 const UINT_32 pb
= mipInfo
[pIn
->mipId
].pitch
/ localOut
.blockWidth
;
3744 const UINT_32 yb
= pIn
->y
/ localOut
.blockHeight
;
3745 const UINT_32 xb
= pIn
->x
/ localOut
.blockWidth
;
3746 const UINT_64 blkIdx
= yb
* pb
+ xb
;
3747 const UINT_32 blkOffset
= ComputeOffsetFromEquation(&m_equationTable
[eqIndex
],
3751 pOut
->addr
= sliceSize
* sliceId
+
3752 mipInfo
[pIn
->mipId
].macroBlockOffset
+
3753 (blkIdx
<< blkSizeLog2
) +
3754 (blkOffset
^ pipeBankXor
);
3758 ret
= ADDR_INVALIDPARAMS
;
3767 ************************************************************************************************************************
3768 * Gfx10Lib::HwlComputeMaxBaseAlignments
3771 * Gets maximum alignments
3773 * maximum alignments
3774 ************************************************************************************************************************
3776 UINT_32
Gfx10Lib::HwlComputeMaxBaseAlignments() const
3778 return GetBlockSize(ADDR_SW_64KB
);
3782 ************************************************************************************************************************
3783 * Gfx10Lib::HwlComputeMaxMetaBaseAlignments
3786 * Gets maximum alignments for metadata
3788 * maximum alignments for metadata
3789 ************************************************************************************************************************
3791 UINT_32
Gfx10Lib::HwlComputeMaxMetaBaseAlignments() const
3793 // Max base alignment for Htile
3794 Dim3d metaBlk
= {0};
3795 const UINT_32 metaBlkSize
= GetMetaBlkSize(Gfx10DataDepthStencil
,
3803 const UINT_32 maxBaseAlignHtile
= Max(metaBlkSize
, 1u << (m_pipesLog2
+ 11u));
3805 // Max base alignment for Cmask
3806 const UINT_32 maxBaseAlignCmask
= GetMetaBlkSize(Gfx10DataFmask
,
3814 // Max base alignment for 2D Dcc
3815 const AddrSwizzleMode ValidSwizzleModeForDcc2D
[] =
3822 UINT_32 maxBaseAlignDcc2D
= 0;
3824 for (UINT_32 swIdx
= 0; swIdx
< sizeof(ValidSwizzleModeForDcc2D
) / sizeof(ValidSwizzleModeForDcc2D
[0]); swIdx
++)
3826 for (UINT_32 bppLog2
= 0; bppLog2
< MaxNumOfBpp
; bppLog2
++)
3828 for (UINT_32 numFragLog2
= 0; numFragLog2
< 4; numFragLog2
++)
3830 const UINT_32 metaBlkSize2D
= GetMetaBlkSize(Gfx10DataColor
,
3832 ValidSwizzleModeForDcc2D
[swIdx
],
3838 maxBaseAlignDcc2D
= Max(maxBaseAlignDcc2D
, metaBlkSize2D
);
3843 // Max base alignment for 3D Dcc
3844 const AddrSwizzleMode ValidSwizzleModeForDcc3D
[] =
3852 UINT_32 maxBaseAlignDcc3D
= 0;
3854 for (UINT_32 swIdx
= 0; swIdx
< sizeof(ValidSwizzleModeForDcc3D
) / sizeof(ValidSwizzleModeForDcc3D
[0]); swIdx
++)
3856 for (UINT_32 bppLog2
= 0; bppLog2
< MaxNumOfBpp
; bppLog2
++)
3858 const UINT_32 metaBlkSize3D
= GetMetaBlkSize(Gfx10DataColor
,
3860 ValidSwizzleModeForDcc3D
[swIdx
],
3866 maxBaseAlignDcc3D
= Max(maxBaseAlignDcc3D
, metaBlkSize3D
);
3870 return Max(Max(maxBaseAlignHtile
, maxBaseAlignCmask
), Max(maxBaseAlignDcc2D
, maxBaseAlignDcc3D
));
3874 ************************************************************************************************************************
3875 * Gfx10Lib::GetMetaElementSizeLog2
3878 * Gets meta data element size log2
3880 * Meta data element size log2
3881 ************************************************************************************************************************
3883 INT_32
Gfx10Lib::GetMetaElementSizeLog2(
3884 Gfx10DataType dataType
) ///< Data surface type
3886 INT_32 elemSizeLog2
= 0;
3888 if (dataType
== Gfx10DataColor
)
3892 else if (dataType
== Gfx10DataDepthStencil
)
3898 ADDR_ASSERT(dataType
== Gfx10DataFmask
);
3902 return elemSizeLog2
;
3906 ************************************************************************************************************************
3907 * Gfx10Lib::GetMetaCacheSizeLog2
3910 * Gets meta data cache line size log2
3912 * Meta data cache line size log2
3913 ************************************************************************************************************************
3915 INT_32
Gfx10Lib::GetMetaCacheSizeLog2(
3916 Gfx10DataType dataType
) ///< Data surface type
3918 INT_32 cacheSizeLog2
= 0;
3920 if (dataType
== Gfx10DataColor
)
3924 else if (dataType
== Gfx10DataDepthStencil
)
3930 ADDR_ASSERT(dataType
== Gfx10DataFmask
);
3933 return cacheSizeLog2
;
3937 ************************************************************************************************************************
3938 * Gfx10Lib::HwlComputeSurfaceInfoLinear
3941 * Internal function to calculate alignment for linear surface
3945 ************************************************************************************************************************
3947 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSurfaceInfoLinear(
3948 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
3949 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
3952 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3954 if (IsTex1d(pIn
->resourceType
) && (pIn
->height
> 1))
3956 returnCode
= ADDR_INVALIDPARAMS
;
3960 const UINT_32 elementBytes
= pIn
->bpp
>> 3;
3961 const UINT_32 pitchAlign
= (pIn
->swizzleMode
== ADDR_SW_LINEAR_GENERAL
) ? 1 : (256 / elementBytes
);
3962 const UINT_32 mipDepth
= (pIn
->resourceType
== ADDR_RSRC_TEX_3D
) ? pIn
->numSlices
: 1;
3963 UINT_32 pitch
= PowTwoAlign(pIn
->width
, pitchAlign
);
3964 UINT_32 actualHeight
= pIn
->height
;
3965 UINT_64 sliceSize
= 0;
3967 if (pIn
->numMipLevels
> 1)
3969 for (INT_32 i
= static_cast<INT_32
>(pIn
->numMipLevels
) - 1; i
>= 0; i
--)
3971 UINT_32 mipWidth
, mipHeight
;
3973 GetMipSize(pIn
->width
, pIn
->height
, 1, i
, &mipWidth
, &mipHeight
);
3975 const UINT_32 mipActualWidth
= PowTwoAlign(mipWidth
, pitchAlign
);
3977 if (pOut
->pMipInfo
!= NULL
)
3979 pOut
->pMipInfo
[i
].pitch
= mipActualWidth
;
3980 pOut
->pMipInfo
[i
].height
= mipHeight
;
3981 pOut
->pMipInfo
[i
].depth
= mipDepth
;
3982 pOut
->pMipInfo
[i
].offset
= sliceSize
;
3983 pOut
->pMipInfo
[i
].mipTailOffset
= 0;
3984 pOut
->pMipInfo
[i
].macroBlockOffset
= sliceSize
;
3987 sliceSize
+= static_cast<UINT_64
>(mipActualWidth
) * mipHeight
* elementBytes
;
3992 returnCode
= ApplyCustomizedPitchHeight(pIn
, elementBytes
, pitchAlign
, &pitch
, &actualHeight
);
3994 if (returnCode
== ADDR_OK
)
3996 sliceSize
= static_cast<UINT_64
>(pitch
) * actualHeight
* elementBytes
;
3998 if (pOut
->pMipInfo
!= NULL
)
4000 pOut
->pMipInfo
[0].pitch
= pitch
;
4001 pOut
->pMipInfo
[0].height
= actualHeight
;
4002 pOut
->pMipInfo
[0].depth
= mipDepth
;
4003 pOut
->pMipInfo
[0].offset
= 0;
4004 pOut
->pMipInfo
[0].mipTailOffset
= 0;
4005 pOut
->pMipInfo
[0].macroBlockOffset
= 0;
4010 if (returnCode
== ADDR_OK
)
4012 pOut
->pitch
= pitch
;
4013 pOut
->height
= actualHeight
;
4014 pOut
->numSlices
= pIn
->numSlices
;
4015 pOut
->sliceSize
= sliceSize
;
4016 pOut
->surfSize
= sliceSize
* pOut
->numSlices
;
4017 pOut
->baseAlign
= (pIn
->swizzleMode
== ADDR_SW_LINEAR_GENERAL
) ? elementBytes
: 256;
4018 pOut
->blockWidth
= pitchAlign
;
4019 pOut
->blockHeight
= 1;
4020 pOut
->blockSlices
= 1;
4022 // Following members are useless on GFX10
4023 pOut
->mipChainPitch
= 0;
4024 pOut
->mipChainHeight
= 0;
4025 pOut
->mipChainSlice
= 0;
4026 pOut
->epitchIsHeight
= FALSE
;
4028 // Post calculation validate
4029 ADDR_ASSERT(pOut
->sliceSize
> 0);